The variable r may not be initialized.

There is 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 it gives:

 $ javac A.java A.java:6: variable r might not have been initialized System.out.println(r); ^ 1 error 
  • Why?
  • How does Runnable refer to a variable pointing to it?

(In the real code there is one more level (listener), and the link through this does not work)

+7
java final
source share
7 answers

To answer the second question:

 Runnable outer = new Object() { public final Runnable r = new Runnable() { public void run() { System.out.println(r); } }; }.r; outer.run(); 

must work.

Here, the compiler sees that r will be initialized through an implicit constructor.

For your tiny example, it would be enough to move final Runnable r outside the main method and say:

 new A().r.run(); 
+5
source share

In this case, you can use "this" to avoid a compilation error:

  final Runnable r = new Runnable() { public void run() { System.out.println(this); } }; 
+4
source share

In this case, your new Runnable is created before r , due to the order of operations before the assignment, everything on the right side of the assignment statement is executed. This means that r not in scope when Runnable is declared, and therefore it does not know what is inside the run method.

+2
source share

There is no r variable in the scope of your run() method, you are trying to print some value during its initialization ... That's why it is "might not have been initialized" .

+1
source share

just use "this" in Runnable instead of "r"))) works fine. Then you do not need to add an β€œexternal” Runnable.

+1
source share

Work code:

 public class A { public static void main(String[] p) { class RunnableHolder { Runnable r; }; final RunnableHolder r = new RunnableHolder(); rr = new Runnable() { public void run() { System.out.println(rr); } }; rrrun(); } } 

Thus, you can use the "incomplete" variable using an auxiliary object.

It looks like this construct (a helper object whose fields can be accessed from Runnable) is exactly what Java developers tried to ban. :)

0
source share
 public class A { private static Runnable r; public static void main(String[] p) { r = new Runnable() { public void run() { System.out.println(r); } }; } } 

That should work! And r does not exist in the scope and therefore cannot be found in an anonymous implementation.

0
source share

All Articles