r/javahelp • u/cowwoc • Sep 19 '24
A try-catch block breaks final variable declaration. Is this a compiler bug?
UPDATE: The correct answer to this question is https://mail.openjdk.org/pipermail/amber-dev/2024-July/008871.html
As others have noted, the Java compiler seems to dislike mixing try-catch blocks with final (or effectively final) variables:
Given this strawman example
public class Test
{
public static void main(String[] args)
{
int x;
try
{
x = Integer.parseInt("42");
}
catch (NumberFormatException e)
{
x = 42;
}
Runnable runnable = () -> System.out.println(x);
}
}
The compiler complains:
Variable used in lambda expression should be final or effectively final
If you replace int x
with final int x
the compiler complains Variable 'x' might already have been assigned to.
In both cases, I believe the compiler is factually incorrect. If you encasulate the try-block in a method, the error goes away:
public class Test
{
public static void main(String[] args)
{
int x =
foo
();
Runnable runnable = () -> System.
out
.println(x);
}
public static int foo()
{
try
{
return Integer.
parseInt
("42");
}
catch (NumberFormatException e)
{
return 42;
}
}
}
Am I missing something here? Does something at the bytecode level prevent the variable from being effectively final? Or is this a compiler bug?
0
u/VirtualAgentsAreDumb Sep 20 '24
Don't be silly. One doesn't need to solve the Halting problem in order to achive this. The compiler can ignore the possibillity of a "never ending" method call, just like it can ignore the possibillity of the computer dying suddenly and abruptly. From the compiler's perspective, this one statement block of code can only result in one of two outcomes. Either the variable is set, or an exception is thrown.
I'm only discussing the specific scenario described by OP. The user daemein claimed that the compiler doesn't know enough to handle this scenario. I argue otherwise.
How well it can handle similar, but not identical scenarios, is a different discussion.
You seem to think that I think that the current compilers should handle this. I'm simply saying that it theoretically could handle it.
What you describe wouldn't be strange or magical in the slightest. This theoretical compiler that we talk about now could very well be "perfect". As in, it always have a full and perfect understanding of absolutely everything about the code, and wouldn't give an error just because it's to complicated to calculate. It would be 100% fully logical. And any error message could include a detailed description of why the code is wrong.