Final variable assignment with try/catch
One way to do this is by introducing a (non-final
) temporary variable, but you said you didn't want to do that.
Another way is to move both branches of the code into a function:
final int x = getValue();
private int getValue() {
try {
return Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
return 42;
}
}
Whether or not this is practical depends on the exact use case.
All in all, as long as x
is a an appropriately-scoped local variable, the most practical general approach might be to leave it non-final
.
If, on the other hand, x
is a member variable, my advice would be to use a non-final
temporary during initialization:
public class C {
private final int x;
public C() {
int x_val;
try {
x_val = Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
x_val = 42;
}
this.x = x_val;
}
}
Related videos on Youtube
Comments
-
dtech almost 4 years
Because I believe it is a good programming practice, I make all my (local or instance) variables
final
if they are intended to be written only once.However, I notice that when a variable assignment can throw an exception you cannot make said variable final:
final int x; try { x = Integer.parseInt("someinput"); } catch(NumberFormatException e) { x = 42; // Compiler error: The final local variable x may already have been assigned }
Is there a way to do this without resorting to a temporary variable? (or is this not the right place for a final modifier?)
-
NPE over 11 yearsI doubt you can do this without a temporary variable.
-
Joop Eggen over 11 years
final int x = makeX();
definitely. (try-catch in function) -
T.J. Crowder over 11 yearsShocking that the JDK still doesn't have a
tryParse
. -
dtech over 11 years@T.J.Crowder definitly, but it is irrelevant in this case since I just used the integer as an example
-
jaco0646 over 9 yearsTo be perfectly clear, the compiler error is incorrect, is it not? There is no circumstance under which x could be assigned twice in the given example.
-
Joshua Goldberg about 8 years@jaco0646, it's asking a lot for the compiler to get that in general when there are multiple lines in the try block where the exception might happen. It would be nice to have an exceptional case for this purpose, though, detecting when the assignment is the last statement in the try.
-
augurar over 7 yearsI guess the real problem is that Java's
try
-catch
statement does not support anelse
case like Python. -
Frans over 3 yearsKotlin has try expressions for this (kotlinlang.org/docs/reference/…). Hopefully they'll be added to Java some day.
-
-
gks over 11 yearsI guess it could reflect an error cannot make a static reference to the non-static method getValue(), so we are suppose to use the static function ,, i may be wrong private static int getValue() ..@NPE
-
dtech over 11 yearsFor a local scope I agree with you, however this most often occurs with instance variables.
-
Stefan over 10 yearsThe compiler is smart enough to know which statements throw which exceptions. It may not be possible in all cases but just like the compiler can tell you in some cases about dead code etc. it should be able to figure out if final would work.
-
Franklin Yu about 8 yearsTo support what @Stefan said, Clang is able to figure this out when compiling Swift.
-
Joshua Goldberg about 8 yearsIf this.x is an object-type like Integer, then you need a little more (sadly). If you leave x_val undeclared, the compiler will complain that it may not have been initialized. If the fall-back for the catch block is null, you need to pre-initialize to null and either redundantly assign null in the catch for clarity (that's my preference) or have an empty catch.
-
Ti Strga over 5 yearsWhat @JoshuaGoldberg says is true even for primitive types. We have exactly the same pattern of code, where the member in the role of
this.x
is a primitiveboolean
, as is the local variable. Even with Java 9, we get "<thing_in_the_role_of_x_val
> may not have been initialized". The lack of control-flow analysis for this situation is frustrating, but easily worked around.