Strange Java compiler warning: incorrect “potential null access warning”

柔情痞子 提交于 2019-12-10 23:56:44

问题


(JDK 1.6.0_23, Eclipse 3.7.0 with "Potential null pointer access" warning level at "Warning") Consider the following example code:

Object obj = null;
for (;;) {
    obj = getObject();
    if (obj != null) break;
    Thread.sleep(25);
}
obj.toString();

I'm getting the following warning on the last line: Potential null pointer access: The variable obj may be null at this location. Is there any real way for obj to actually be null or why the compiler thinks so?


回答1:


The compiler is seeing this as a potential that the object will not be initialized. It is not really able to see that the loop breaking condition is that the object is not null or it will just run forever or until it is no longer null. I only get the warning on the JDK you mentioned. Using a more updated version this warning does not appear.




回答2:


I'd say the compiler sees this as:

Object obj = null;
[Too dumb to interpret this loop]
obj.toString();

So obj.toString() could be null if you cannot interpret what the loop does.

For example you can trick the compiler by replacing:

void x(int x){
    return;  
    x++;  //error unreachable code
}

with

void x(int x){
    if(true) return;
    x++;  //compiles
}



回答3:


It seems that compiler cannot analyze the code very well. It actually cannot "run" it and understand that your if statement prevents null access. I played a little bit with the code and found the following equivalent version that does not produce warning:

    Object obj = null;
    do {
        obj = getObject();
        if (obj == null) {
            Thread.sleep(25);
        }
    } while (obj == null);
    obj.toString();

Yes, I know that this version performs 2 null checks on each loop iteration instead of one. So, it is up to you to change your code, add @SuppressWarning to your code or to remove Thread.sleep(25)




回答4:


This is an improved version of AlexR's code which I think is a nice solution to the problem while also improving readability of the code. My version features a second obj = getObject(); line, but doesn't need the second check, so it should be more performant overall.

Object obj = null;
obj = getObject();
while (obj == null) {
    Thread.sleep(25);
    obj = getObject();
}
obj.toString();



回答5:


I know it's an old thread, but how about this? I find it more readable than the versions of Koraktor and AlexR.

Object obj = null;
for (obj=getObject(); obj==null; obj=getObject()) {
  Thread.sleep(25);
}
obj.toString();

But in my code, I usually have enabled "Include 'assert' in null analysis" in eclipse compiler settings and add an assert. So I don't have to change control flow and at the same time avoid the warning:

Object obj = null;    
while (true) {
    obj = getObject();
    if (obj != null) break;
    Thread.sleep(25);
}
assert obj!=null;
obj.toString();


来源:https://stackoverflow.com/questions/6772129/strange-java-compiler-warning-incorrect-potential-null-access-warning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!