Why can't finally{} acces in-try{} variables?

T

Timo Nentwig

Bent said:
The program may pop out of the try-block into the finally-block before
a given try-block variable has been declared. Does it seem reasonable
that this try-block variable should then be visible in the
finally-block?

Yes, it is. If I declare the variable outside of try{} it will be null. And
so it will be in finally{} if you leave try{}.
 
T

Timo Nentwig

Bent said:
The program may pop out of the try-block into the finally-block before
a given try-block variable has been declared. Does it seem reasonable
that this try-block variable should then be visible in the
finally-block?

Yes, it is. If I declare the variable outside of try{} it will be null. And
so it will be in finally{} if you leave try{}.
 
T

Tony Morris

Timo Nentwig said:
Hi!

Is there any reason why I cannot do this:

try
{
final PreparedStatement st = con.prepareStatement(sql);
..
}
catch..
finally
{
if(st!=null) st.close();
}

??

I have to declare st outside of try and therefore cannot make it final
anymore. Besides I don't understand the sense why finally cannot access
variables inside try.

Can somebody explain?

Regards,
Timo

The problem you are having is not specifically related to
try{}catch{}finally{} blocks, but is entirely related to "scope".
http://java.sun.com/tutorial describes the concept in detail.


--
Tony Morris
(BInfTech, Cert 3 I.T., SCJP[1.4], SCJD)
Software Engineer
IBM Australia - Tivoli Security Software
(2003 VTR1000F)
 
B

Bent C Dalager

Yes, it is. If I declare the variable outside of try{} it will be null. And
so it will be in finally{} if you leave try{}.

I was thinking of variables declared within the actual try-block.
Variables that haven't been declared yet usually aren't null.

Cheers
Bent D
 
B

Bent C Dalager

Actually, it's not so unreasonble: just because the language
allows you to declare a variable anywhere in the source code
doesn't mean that's how it really works in the executable.
And you could check if variable is undefined, too. It's not
exactly rocket science, e.g. Perl does that.

So what you're proposing is a new keyword for handling undeclared
variables in finally-blocks? If so, it seems a bit of a heavy-handed
solution to a very minor issue.
But that's not the point. My point was: the purpose of finally{}
is to clean up resources allocated in try{}. So how TF am I
supposed to do that if I can't get to those variables?

Some times that is the purpose, other times it is not. Whatever the
case, it doesn't seem wholly inappropriate to declare such resources
outside of both blocks.

Cheers
Bent D
 
T

Timo Nentwig

Bent said:
I was thinking of variables declared within the actual try-block.
Variables that haven't been declared yet usually aren't null.

try
{
Blah blah = new Blah();
blah.work(); // throws exception
Blah2 blah2= new Blah2();
...
}
catch..
finally
{
if(blah!=null)blah.cleanup();
if(blah2...
}
 
T

Timo Nentwig

Timo said:
try
{
Blah blah = new Blah();
blah.work(); // throws exception
Blah2 blah2= new Blah2();

Blah blah = null;
Blah2 blah2 = null;
try
{
blah = new Blah();
blah.work(); // throws exception
blah2 = new Blah2();
}
....
 
B

Bent C Dalager

try
{
Blah blah = new Blah();
blah.work(); // throws exception
Blah2 blah2= new Blah2();
...
}
catch..
finally
{
if(blah!=null)blah.cleanup();
if(blah2...
}

This will tend to not compile based on the reason I gave above. What
are you trying to say?

Cheers
Bent D
 
D

Dimitri Maziuk

Bent C Dalager sez:
So what you're proposing is a new keyword for handling undeclared
variables in finally-blocks? If so, it seems a bit of a heavy-handed
solution to a very minor issue.


Some times that is the purpose, other times it is not. Whatever the
case, it doesn't seem wholly inappropriate to declare such resources
outside of both blocks.

I said that two posts ago -- in practice implementing that is not
worth the trouble, decalring those resources outside of the block
works in all cases except OP's one: when local variable is declared
final. And that's something nobody does anyway.

Dima
 
C

Chris Smith

Timo said:
try
{
Blah blah = new Blah();
blah.work(); // throws exception
Blah2 blah2= new Blah2();
...
}
catch..
finally
{
if(blah!=null)blah.cleanup();
if(blah2...
}

Timo,

I think you're missing a distinction. Local variables that are declared
and not initialized are *not* given an initial value of null. They are
considered no definitely assigned, and it is a compile-time error to
access them before assigning a value.

I appreciate that you may be suggesting a change to the language to work
around this, but you haven't been clear on what that is. Do you want to
give all local reference variables an initial value of null? Do you
just want to do that for variables declared in try blocks? Or do you
wish to specify that the compiler has to differentiate based on the
location where the exception is thrown, so that all variables that
haven't been definitely assigned at that point are set to null at the
beginning of the try block? Is it only reference variables local to the
block that should be made available in the finally block, or primitives
as well; and if the latter, are they also to be artificially definitely
assigned, and to what values?

All of those options seem to me to have substantial disadvantages, but
it's hard to articulate them when you haven't defined what you want.

All of this could be easily avoided if you would simply not try to
combine try/catch and try/finally in the same construct. Doing so leads
to a large number of awkward problems... mostly because you want
try/catch to surround all the code that could throw an exception, but
try/finally to surround just that code where cleanup is necessary.
Because of this, I find it better to wrote:

try
{
final PreparedStatement stmt = con.prepareStatement(...);

try
{
...
}
finally
{
con.close();
}
}
catch (SQLException e)
{
...
}

Typically, though, I tend to factor code at a smaller granularity than
that, so the try/catch block would be in one method, and the try/finally
in a separate method. It seems that dealing with an SQLException and
running a query (including closing the connection, of course) are
separate enough that they don't need to belong in the same method.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

Bryan Bullard

Definite assignment says that a local variable must be
definitely assigned a value before its value is accessed. Sun considers this
so important that they devoted an entire chapter of the Java Language
Specification to the subject

[...]

right, you make a *very* good point. however, i would still have to say
that the justification is more multifaceted than just definite assignment.

A study of program structure has revealed that programs can differ
tremendously in their intellectual manageability. A number of rules have
been discovered, violations of which will either seriously impair or totally
destroy the intellectual manageability of the program.--E. Dijkstra
 
D

Dale King

Bryan Bullard said:
Definite assignment says that a local variable must be
definitely assigned a value before its value is accessed. Sun considers this
so important that they devoted an entire chapter of the Java Language
Specification to the subject

[...]

right, you make a *very* good point. however, i would still have to say
that the justification is more multifaceted than just definite assignment.


I didn't say it wasn't. I was responding to a post that basically said that
the only issue was scoping rules. All I said is that concern is pretty much
non-existent next to definite assignment. Sure there are other concerns, but
I think definite assignment is the primary one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,588
Members
45,100
Latest member
MelodeeFaj
Top