Weird false-positive of javac data flow analysis

一笑奈何 提交于 2020-01-13 13:53:45

问题


I have code of the following form:

class Test {
  private final A t;

  public Test() {

    for ( ... : ... ) {
      final A u = null;
    }

    t = new A();
  }

  private class A {}
}

Compiler says:

variable t might already have been assigned

Interestingly, if I perform any of the following changes to the loop it works out!

  • Change the loop's content to A u = null
  • Remove the loop (but keep final A u = null;)
  • Replace the foreach-style loop with a classic counting loop

What is going on here?

Note: I could not get the minimal example to cause the error so there is probably something wrong with the "environment" (about 1400 loc). I can not see what could disturb the initialisation of t, though, as t is written to nowhere else.

Fun fact: IntelliJ IDEA says "Variable 'u' can have 'final' modifier..." if I remove it.

I use javac 1.6.0_26.

Update: There you go, this example so so minimal:

import java.util.List;

class A {
  private final boolean a;

  public A() {
    for ( final Object o : new Object[] {} ) {
      final Object sh = null;
    }

    a = true;
  }

  class B {
    private final Object b1;
    private final Object b2;

    B() {
      b1 = null;
      b2 = null;
    }
  }
}

Fails to compile on javac 1.6.0_26 but compiles on javac 1.7.0_02. So I guess I hit some wicked corner case of ... something?

Note that you can do any of

  • Remove any one member
  • Remove final inside the loop in A()
  • Replace the loop with a normal for loop, e.g. for ( int i=0; i<100; i++ ) { ... }

and it will compile.


回答1:


If you have lots of code I would try this.

private final A t;

public Test() {
    final int t = 1;

   for ( ... ) {
      final A u = null;
   }

   this.t = new A();

This will cause any code which "might" initialise t to fail (and show up in the compiler.




回答2:


If you're constructor happen to call another constructor that doesn't itself set t, the compiler fails to understand that.

See here.




回答3:


As the problem is fixed in Java 7, it is probably a bug in the Java 6 compiler.




回答4:


It is my understanding that storing an object in a final var does not make your object immutable but its reference. That explain why when you remove the final keyword it works and as per removing the for-loop, i think you are accessing the object reference and not an instance.



来源:https://stackoverflow.com/questions/9112927/weird-false-positive-of-javac-data-flow-analysis

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