"final" bug??

R

Roedy Green

Consider the following code

static final String allpads;

static
{
try
{
allPads = HunkIO.readEntireFile( ALLPADS_FILE );
}
catch ( IOException e )
{
err.println( "Unable to access allPads.pad" );
allPads = null;
}
}

According to the IntelliJ inspector, this allPads should be final.
But according to Javac, it should not, claiming I might be trying to
redefine a final.

Which is correct and why?
--
Roedy Green Canadian Mind Products
http://mindprod.com

"Species evolve exactly as if they were adapting as best they could to a changing world, and not at all as if they were moving toward a set goal."
~ George Gaylord Simpson
 
L

Lew

Roedy said:
Consider the following code

static final String allpads;

static
{
try
{
allPads = HunkIO.readEntireFile( ALLPADS_FILE );
}
catch ( IOException e )
{
err.println( "Unable to access allPads.pad" );
allPads = null;
}
}

According to the IntelliJ inspector, this allPads should be final.
But according to Javac, it should not, claiming I might be trying to
redefine a final.

Which is correct and why?

I suspect javac is correct, according to how I read s. 16.2.15 of the JLS. It
seems to hinge on whether 'allPads' is definitely assigned or definitely
unassigned after the 'readEntireFile()' assignment statement. S. 16.8 seems
to apply, also. The way I read the spec, you cannot say that 'allPad' is
definitely unassigned at the end of the 'try' block, therefore it is not
definitely unassigned before the 'catch' block, therefore the assignment
inside the 'catch' block is potentially a re-assignment.

Regardless, the fix is simple:

static final String allPads;
static
{
String ap;
try
{
aP = HunkIO.readEntireFile( ALLPADS_FILE );
}
catch ( IOException e )
{
err.println( "Unable to access "+ ALLPADS_FILE );
aP = null;
}
allPads = ap;
}
 
E

Eric Sosman

Roedy said:
Consider the following code

static final String allpads;

static
{
try
{
allPads = HunkIO.readEntireFile( ALLPADS_FILE );
}
catch ( IOException e )
{
err.println( "Unable to access allPads.pad" );
allPads = null;
}
}

According to the IntelliJ inspector, this allPads should be final.
But according to Javac, it should not, claiming I might be trying to
redefine a final.

Which is correct and why?

There's probably something in the JLS, if you feel like
playing Language Lawyer (or at least Language Law Clerk) for
a while. I'd probably just dodge the issue and write

static {
String s = null;
try {
s = HunkIO.readEntireFile( ALLPADS_FILE );
catch (IOException e) {
err.println("Unable to access allPads.pad");
}
allPads = s;
}

Aside: The error message would be more helpful if it
didn't lose the information carried in the IOException, and
mightn't "allPads.pad" be better as ALLPADS_FILE?
 
L

Lew

Eric said:
There's probably something in the JLS, if you feel like
playing Language Lawyer (or at least Language Law Clerk) for
a while. I'd probably just dodge the issue and write

static {
String s = null;
try {
s = HunkIO.readEntireFile( ALLPADS_FILE );
catch (IOException e) {
err.println("Unable to access allPads.pad");
}
allPads = s;
}

Aside: The error message would be more helpful if it
didn't lose the information carried in the IOException, and
mightn't "allPads.pad" be better as ALLPADS_FILE?

Great minds think alike.

I prefer the idiom where the 'String s = null;' is just 'String s;' and the
assignment occurs in both the 'try' and 'catch' blocks. Others prefer
redundant assignment to redundant typing.

I think avoiding redundant typing is somewhat the wrong kind of laziness,
sometimes. In this particular case, the redundant assignment is low overhead,
but one expects it to occur most of the time and therefore to be avoided, but
only at class initialization and therefore who cares, but putting it
separately in the 'catch' block more clearly documents the intent of the logic
than the redundant assignment does, so I care.
 
R

Roedy Green

Regardless, the fix is simple:

static final String allPads;
static
{
String ap;
try
{
aP = HunkIO.readEntireFile( ALLPADS_FILE );
}
catch ( IOException e )
{
err.println( "Unable to access "+ ALLPADS_FILE );
aP = null;
}
allP

That sounds counter intuitive. If ap is ambiguously assigned in the
same pattern, so much be allp???

I'd think you might have to do:

String ap = null;

I will experiment.

That's for the tip. This has been very infuriating, because the
automated refactoring tools alternate between putting the final in and
out like Oscar Wilde with a comma.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"Species evolve exactly as if they were adapting as best they could to a changing world, and not at all as if they were moving toward a set goal."
~ George Gaylord Simpson
 
R

Roedy Green

That sounds counter intuitive. If ap is ambiguously assigned in the
same pattern, so much be allp???

I'd think you might have to do:

String ap = null;

I will experiment.

To beat a dead cow:

The compiler is worried that somehow the exception might happen AFTER
ap is set, e.g.

static
{
String ap;
try
{
ap = HunkIO.readEntireFile( ALLPADS_FILE );
doSomethingDangrous();
}
catch ( IOException e )
{
err.println( "Unable to access allPads.pad" );
ap = null;
}
allPads = ap;
}

does work because ap is NOT final. It does not care if ap gets
assigned twice.

static
{

try
{
allPads = HunkIO.readEntireFile( ALLPADS_FILE );
doSomethingDangrous();
}
catch ( IOException e )
{
err.println( "Unable to access allPads.pad" );
allPads= null;
}
}

does not work because allPads is final. It would be in deep trouble if
doSomethingDangerous triggered the exception.
The code will not work because then allPads would be assigned twice.
Java is does not guarantee sufficient analysis to realise no exception
is possible after allPads is assigned.

--
Roedy Green Canadian Mind Products
http://mindprod.com

"Species evolve exactly as if they were adapting as best they could to a changing world, and not at all as if they were moving toward a set goal."
~ George Gaylord Simpson
 
L

Lew

Roedy said:
That sounds counter intuitive. If ap is ambiguously assigned in the
same pattern, so much be allp???

I'd think you might have to do:

String ap = null;

I will experiment.

"aP" is not a final variable, and it is definitely assigned after the
"try-catch" construct. My comments were about it being definitely
*un*assigned *before* the 'catch' block, a different thing altogether.

I have used the idiom I outlined countless times. It works.

-
Lew
 
C

charlesbos73

I prefer the idiom where the 'String s = null;' is just 'String s;' and the
assignment occurs in both the 'try' and 'catch' blocks. Others prefer
redundant assignment to redundant typing.

I use Eric's idiom all the time.

But please don't pretend you know why.

It's not because I prefer "redundant assignment" but
because I prefer to have as few logic as possible in
my catch clause. The catch clause in this case is
good for error logging.

A try/catch is not an if/else block, unlike you
like goto-programming and like to use exceptions
for flow control.
 
L

Lew

charlesbos73 said:
I use Eric's idiom all the time.

But please don't pretend you know why.

It's not because I prefer "redundant assignment" but
because I prefer to have as few logic as possible in
my catch clause. The catch clause in this case is
good for error logging.

A try/catch is not an if/else block, unlike you
like goto-programming and like to use exceptions
for flow control.

Either you continue from 'catch', making the first assignment nearly always
redundant, or you don't, making it always redundant. In the first case, you
are using the 'catch' as part of the logic flow, killing your stated reason.
In that scenario, the extra assignment is usually not needed. In the second,
you don't ever need the extra assignment, neither before the 'try' nor in the
'catch'.

Whatever your avowed reason, the result is that you are eschewing redundant
typing in favor of a (nearly-)always useless double assignment.
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top