簡體   English   中英

為什么引用匿名內部類的名稱在它是成員時起作用,而不是變量?

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

對不起標題血,我不知道如何在一行中描述問題。 如果你有建議,我會公開的。

假設您有以下課程:

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
            }
        }
    }
}

為什么memberRunnable能夠從run()內部訪問自己,而varRunnable不是? AFAICS它是完全相同的結構。

我知道,顯然你可以使用this 我只是想知道為什么編譯器會在兩種情況之間產生差異,這兩種情況看起來完全相同。 也是為什么它認為varRunnable可能沒有被初始化,當它顯然是在那時。

有人可能會說,如果Runnable是一個類(它是一個接口),它的構造函數可能會嘗試調用run() ,因此實際上會遇到引用未初始化的場景。 但是,這也應該是memberRunnable的情況,但是這種情況有效。

有趣的是,如果使用類而不是Runnable ,則沒有任何變化,在這種情況下,上面的場景(構造函數調用重寫方法)實際上可能發生。 這意味着,在這種情況下,您可以在運行時遇到“未初始化的字段”(雖然沒有嘗試過),這是相當愚蠢的,因為編譯器應該防范它。

也是為什么它認為varRunnable可能沒有被初始化,當它顯然是在那時。

不,該變量不是(在一般情況下)保證在該點初始化。

假設,僅僅為了參數, Runnable是一個抽象類(而不是一個接口), Runnable的構造函數叫做this.run() 由於Runnable構造發生在賦值之前,這將導致在賦值發生之前訪問varRunnable

換句話說,它將導致訪問未初始化的局部變量。 請注意,這比訪問尚未顯式初始化的字段更糟糕,因為局部變量未初始化為默認值。 事實上更糟糕的是,禁止訪問未初始化的局部變量,而允許訪問尚未顯式初始化的字段,正如您剛剛發現的那樣。 (使字段最終不會改變這一點。最終字段也有默認值,它們實際上可以在構造函數中更改(一次)。)

資料來源:我是一名javac開發人員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM