I came across a behavior, I didn't knew of earlier, in the follow up code.
Consider the 1st case:
public static void main(String[] args) {
final String str = null;
System.out.println(str.length()); // Compiler Warning: NullPointerAccess
}
As expected, the compiler shows me following warning on str
being null - Null pointer access: The variable str can only be null at this location.
Now, when I moved that variable a static final field initialized to null:
class Demo {
static final String str = null;
public static void main(String[] args) {
System.out.println(str.length()); // No Compiler Warning
}
}
Now, compiler doesn't show any warning. AFAIK, Compiler should know that str
being final, will not change its value, at any point of the code. And given that it is null
, will definitely result in NullPointerException
later on, which it does.
Although, compiler successfully warns me of this in the first case, why it cannot identify this in the 2nd case. Why this change of behaviour? The behaviour is same, if I change static
field to instance
field, and access it using an instance of Demo
.
I thought this behaviour might have been specified in JLS, so I went through the topic Definite Assignment, but didn't find anything related to this issue. Can anyone explain the change in behaviour? I'm looking for some strong point with some link to JLS if possible?
Apart from that, why compiler shows me only warning in the first place, as I think for the same reason I stated above, the method invocation will definitely throw NPE at runtime, since the field can't be changed? Why didn't it rather show me a Compiler Error? Am I expecting too much from compiler, as it seems to be quite obvious, that the runtime result of str.length()
can't be anything than NPE
?
Sorry for missing that earlier:
I'm using Eclipse Juno, on Ubuntu 12.04 with OpenJDK 7.
The static keyword means the value is the same for every instance of the class. The final keyword means once the variable is assigned a value it can never be changed. The combination of static final in Java is how to create a constant value.
AFAIK, Compiler should know that str being final, will not change its value, at any point of the code. And given that it is null , will definitely result in NullPointerException later on, which it does.
We can initialize a final static variable at the time of declaration. Initialize inside a static block : We can also initialize a final static variable inside a static block because we should initialize a final static variable before class and we know that static block is executed before main() method.
Initializing a final Variable You can initialize a final variable when it is declared. This approach is the most common. A final variable is called a blank final variable if it is not initialized while declaration. Below are the two ways to initialize a blank final variable.
I am not sure in 100%, but in the second case where you have final field against local variable, there is possible assigns to this final field some value direct in static (or instance block depending if variable is static or not) initialization block:
class Demo {
...
static {
str = "some text";
}
...
}
so compiler don't give you warn.
Wow! It turned out, it was eclipse specific issue. When I compiled the code using:
javac -Xlint:all Demo.java
it didn't show any warning for any case. So, I went back to eclipse to check any settings enabled for this case, and found one.
In Windows -> Preferences -> Java -> Compiler -> Errors/Warnings, under Null Analysis, I can change the way the Null Pointer Access should be treated by Eclipse Compiler. I can set it to - Ignore, Error, or Warning.
And now it seems like a completely silly question. Shame on me. :(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With