2012-11-09 64 views
3

考慮以下幾點:在接口中聲明的匿名內部類:什麼是外部類?

public class OuterClass { 

    private String attribute = "outer"; 

    class InnerClass { 
     private String attribute = "inner"; 
     public doSomething() { 
      System.out.println(this.attribute); 
      System.out.println(OuterClass.this.attribute); 

     } 
    } 

} 

的是將InnerClass不是靜態的,必須對一個實例被創建它的外部類。

new OuterClass().new InnerClass()

常規內部類保持在其中創建它的外類的引用,可訪問使用Outer.this.myAttribute在這種情況下有一個「命名colision」

特別有用

創建匿名內部類時,它是一樣的:創建的匿名內部類擁有對外部類的引用,這就是爲什麼當在方法內部聲明謂詞時(匿名我們仍然可以在內部類中訪問外部類的變量,而不必將它們聲明爲final(而我們應該將變量作爲方法參數傳遞。

public class OuterClass { 

    // Do not need to be final because the innerclass keeps a reference to the outerclass 
    // even if it's an anonymous innerclass, it's still an innerclass 
    private String classAttribute = "classAttribute"; 

    public Runnable doSomething() { 

    // Should be final because the variable lives on the stack and the reference to this object 
    // must be copied so that the String object is still accessible when the stack frame is destroyed 
    final String localVar = "localVar"; 

    return new Runnable() { 
     @Override 
     public void run() { 
     System.out.println(classAttribute); 
     System.out.println(localVar); 
     } 
    }; 
    } 

} 

最後,我們可以聲明常量的接口,這是隱式標有公共靜態決賽。一個對象可以是一個常量。 因此,創建爲匿名內部類的對象是接口的合法常量。

例如,在使用番石榴時,我通常在我的界面中聲明函數和謂詞,這些函數和謂詞允許我使用有用的番石榴函數,如Maps.uniqueIndex(...)

public interface AlternativeNameable { 

    String getAlternativeName(); 

    Function<AlternativeNameable,String> GET_ALTERNATIVE_NAME = new Function<AlternativeNameable,String>() { 
    @Override 
    public String apply(AlternativeNameable input) { 
     return input.getAlternativeName(); 
    } 
    }; 

} 

所以,你可能會問自己什麼是我的問題嗎?這是:

當聲明一個匿名類作爲接口常量(請參閱我的最後一個代碼示例),在哪個外部類中,匿名內部類持有對引用的引用?

+0

你試過調試嗎? –

+0

剛剛嘗試過,函數實例中沒有任何屬性 –

回答

2

接口的內部類是隱式靜態的,因此不需要引用外部類。

+0

所以,你的意思是匿名內部類,在這種特殊情況下,就像一個「匿名靜態內部類」?我理解這個概念,但是你有解釋它的任何鏈接嗎? –

+0

@SebastienLorber http://docs.oracle。COM/JavaSE的/規格/ JLS/SE7/HTML/JLS-9.html#JLS-9.5 –

4

接口always implicitly have the modifiers public static final中定義的字段。這是一個常數,因此它沒有相關的外部類。

另外,member types of interfaces are implicitly public and static也適用於匿名類。

+2

因此,隱含的'static'在這裏是關鍵嗎? –

+0

那,以及接口本身的隱含「靜態」。接口,枚舉和註解總是「靜態」的。 –

+0

這就是我解釋的。但是對該函數的引用是靜態的並不能解釋爲什麼它不像另一個匿名內部類。確實有可能持有對引用外部類的任何聲明類的靜態引用。 –