Sorry for the title gore, I did not know how to describe the problem in one line. If you have suggestions, I'm open.
Suppose you have the following class:
public class SomeClass {
// doesn't even need to be final, which is freaky
Runnable memberRunnable = new Runnable() {
public void run() {
SomeOtherClass.someMethod(memberRunnable); // this works
}
}
public void someMethod() {
final Runnable varRunnable = new Runnable() {
public void run() {
SomeOtherClass.someMethod(varRunnable); // compiler error - "varRunnable" might not have been initialized
}
}
}
}
Why is the memberRunnable
able to access itself from inside run()
, while varRunnable
is not? AFAICS it's the exact same construct.
You can obviously use this
instead, I know. I'm just wondering why the compiler makes a difference between the two cases, which seem identical. Also why it thinks varRunnable
might not have been initialized, when it's obvious that it is at that point.
One could argue that, if Runnable
was a class (it's an interface), it's constructor might be trying to call run()
, thus actually running into a scenario where the reference is uninitialized. However, this should also be the case for memberRunnable
, but that case works.
Funny thing, nothing changes if instead of Runnable
you use a class, in which case the above scenario (constructor calling an overridden method) can actually happen. This means that, in that case, you can run into a "field not initialized" at runtime (haven't tried it though), which is rather dumb since the compiler should guard against that.