问题
There's a very simple program:
public class A {
public static void main(String[] p) {
final Runnable r = new Runnable() {
public void run() {
System.out.println(r);
}
};
r.run();
}
}
And this gives:
$ javac A.java
A.java:6: variable r might not have been initialized
System.out.println(r);
^
1 error
- Why?
- How can a Runnable reference a variable pointing to it?
(In the real code, there is one more level (a listener), and referencing via this
does not work)
回答1:
In this case, you can use "this" to avoid the compilation error:
final Runnable r = new Runnable() {
public void run() {
System.out.println(this); // Avoid compilation error by using this
}
};
回答2:
To answer your second question:
Runnable outer = new Object() {
public final Runnable r = new Runnable() {
public void run() {
System.out.println(r);
}
};
}.r;
outer.run();
should work.
Here the compiler sees that r will have been initialized through the implicit constructor.
For your tiny example, it would be enough to move the final Runnable r
outside the main method and say:
new A().r.run();
回答3:
In this case your new Runnable
is being created before r
, because of order of operations everything to the right side of an assignment operator is performed before the assignment. This means that r
is not in scope when your Runnable is declared, and thus it doesn't know what it is inside the run
method.
回答4:
There's no r
variable in the scope of your run()
method, you are trying to print out some value during it's initialization... That's why it "might not have been initialized"
.
回答5:
just use "this" in the Runnable in the place of "r" ))) works fine. Then you do not need to add the "outer" Runnable.
回答6:
The working code is:
public class A {
public static void main(String[] p) {
class RunnableHolder { Runnable r; };
final RunnableHolder r = new RunnableHolder();
r.r = new Runnable() {
public void run() {
System.out.println(r.r);
}
};
r.r.run();
}
}
So it is possible to "unfinal" a variable using an auxiliary object.
It looks like this construct (an auxiliary object whose fields may be accessed from a Runnable) is exactly what the designers of Java tried to disallow. :)
回答7:
public class A {
private static Runnable r;
public static void main(String[] p) {
r = new Runnable() {
public void run() {
System.out.println(r);
}
};
}
}
This should work! And there is no r in the scope of run and thus it cannot be found in the anonymous implementation.
来源:https://stackoverflow.com/questions/19931397/variable-r-might-not-have-been-initialized