简体   繁体   English

为什么引用匿名内部类的名称在它是成员时起作用,而不是变量?

[英]Why does referencing an anonymous inner class by its name work when it's a member, but not a variable?

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? 为什么memberRunnable能够从run()内部访问自己,而varRunnable不是? AFAICS it's the exact same construct. AFAICS它是完全相同的结构。

You can obviously use this instead, I know. 我知道,显然你可以使用this 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. 也是为什么它认为varRunnable可能没有被初始化,当它显然是在那时。

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. 有人可能会说,如果Runnable是一个类(它是一个接口),它的构造函数可能会尝试调用run() ,因此实际上会遇到引用未初始化的场景。 However, this should also be the case for memberRunnable , but that case works. 但是,这也应该是memberRunnable的情况,但是这种情况有效。

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. 有趣的是,如果使用类而不是Runnable ,则没有任何变化,在这种情况下,上面的场景(构造函数调用重写方法)实际上可能发生。 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. 这意味着,在这种情况下,您可以在运行时遇到“未初始化的字段”(虽然没有尝试过),这是相当愚蠢的,因为编译器应该防范它。

Also why it thinks varRunnable might not have been initialized, when it's obvious that it is at that point. 也是为什么它认为varRunnable可能没有被初始化,当它显然是在那时。

No, the variable is not (in the general case) guaranteed to be initialized at that point. 不,该变量不是(在一般情况下)保证在该点初始化。

Suppose, just for the sake of argument, that Runnable was an abstract class (rather than an interface) and that the constructor of Runnable called this.run() . 假设,仅仅为了参数, Runnable是一个抽象类(而不是一个接口), Runnable的构造函数叫做this.run() Since construction of the Runnable occurs before the assignment, this would result in access of varRunnable before the assignment had occurred. 由于Runnable构造发生在赋值之前,这将导致在赋值发生之前访问varRunnable

In other words, it would lead to access of an uninitialized local variable. 换句话说,它将导致访问未初始化的局部变量。 Note that this is worse than accessing a field that has not yet been explicitly initialized, since local variables are not initialized to default values. 请注意,这比访问尚未显式初始化的字段更糟糕,因为局部变量未初始化为默认值。 It's so much worse in fact, that access of uninitialized local variables is forbidden, while access to fields that have not been explicitly initialized is allowed, as you just discovered. 事实上更糟糕的是,禁止访问未初始化的局部变量,而允许访问尚未显式初始化的字段,正如您刚刚发现的那样。 (Making the field final doesn't change this. Final fields also have default values, and they can in fact change (once) in the constructor.) (使字段最终不会改变这一点。最终字段也有默认值,它们实际上可以在构造函数中更改(一次)。)

Source: I'm a javac developer. 资料来源:我是一名javac开发人员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在定义之前引用匿名内部类 - Referencing an anonymous inner class before its definition 匿名内部类中的接口如何工作? - How does the interface in anonymous inner class work? 匿名内部类中的变量名称可以与类外部的参数相同。 为什么? - Variable name in an anonymous inner class can be the same as a parameter outside of class. Why? 成员级别的匿名内部类 - Anonymous inner class at member level 匿名内部类在访问其原语等时是否始终捕获对“this”(外部)对象的引用? - Does an anonymous inner class always capture a reference to “this” (outer) object when accessing its primitives etc.? java解决从匿名内部类访问变量不起作用 - java work around to access a variable from anonymous inner class not working 为什么this.getClass给它自己的类名而不是匿名类名? - Why does this.getClass give it's own class name rather than Anonymous class name? 为什么ArrayList的非静态内部类SubList有一个成员变量“parent”? - Why ArrayList's non-static inner class SubList has a member variable “parent”? 为什么它被称为“匿名”内部阶级? - Why is it called an “anonymous” inner class? 如何在Eclipse中找到一个匿名内部类,只给出它的合成名称(Class $ N)? - How can I find an anonymous inner class in Eclipse given only its synthetic name (Class$N)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM