2011-09-01 42 views
0

我在這裏遇到了一個奇怪的結果,並不確定它是Java中的錯誤還是預期的行爲。我有一個內部類,我已經使用反射來獲取聲明的字段(class.getDeclaredFields())。但是,當我遍歷字段列表並檢查單個類型時,「this」字段將返回外部類而不是內部類。JDK6中的內部類中的「this」錯誤的字段類型?

這是預期的行爲?我覺得很奇怪。

例:

import java.lang.reflect.Field; 

public class OuterClass { 

    public class InnerClass{ 
     public String innerClassString; 
      public InnerClass innerClass; 

    } 


    public static void main(String[] args) { 

     // print the fields of the inner class 
     for(Field field : OuterClass.InnerClass.class.getDeclaredFields()) 
      System.out.println(field.getName() + " ::: " + field.getType()); 
    } 
} 

輸出:

innerClassString ::: class java.lang.String 
innerClass ::: class OuterClass$InnerClass 
this$0 ::: class OuterClass 

我預計在$ 0是類型OuterClass.InnerClass的。

這是一個Java錯誤?無論如何要解決這種意外的行爲?

謝謝,

埃裏克

+4

99.99%,你幾乎可以認爲它不與被數以百萬計的世界各地的開發框架的錯誤。 – StriplingWarrior

+0

我同意。不過,我之前在SO上看到過類似的帖子,指出Java7中修正了這個指針的一個錯誤,所以這讓我感到驚訝。 (http://stackoverflow.com/questions/4823278/inner-class-type-parameter-bound-by-enclosing-class-type-variable) –

+0

'這個$ 0'是對外部類對象的引用。它本身不需要對Inner類對象的引用。即'this' –

回答

9

每個非靜態內部類維護保持到它被實例化用於外類的引用的不可見的ivar。這就是this$0

將InnerClass更改爲public static class並查看區別。

爲了清楚起見,Oracle建議此術語:

http://download.oracle.com/javase/tutorial/java/javaOO/nested.html

術語:嵌套類分爲兩類:靜態和非靜態的。 聲明爲靜態的嵌套類簡單地稱爲靜態嵌套類非靜態嵌套類被稱爲內部類

...

的將InnerClass一個實例只能內的在OuterClass的實例存在並有方法及其外圍實例字段的直接訪問。 ...

要實例化一個內部類,您必須首先實例化外部類。然後,創建外部對象內的內部對象與此語法:

OuterClass.InnerClass innerObject = outerObject.new InnerClass(); 

===

有沒有到這個$ 0變量的任何訪問,然後從內部類中,如果你想?

在內部類的方法,你可以說:

OuterClass outer = OuterClass.this; 

System.out.println(OuterClass.this.toString()); 

這個這個特殊的變種 - OuterClass.this - 正在訪問this$0伊娃 - 它將返回OuterClass實例。請注意,這與在InnerClass方法內使用常規this不同,後者將返回當前的InnerClass實例。

===

此外,我怎麼能確定,如果我處理「這個$ 0」現場不使用字符串比較?

我不清楚你想做什麼,所以我不能推薦如何實現你想要的。

+0

如果你想要的話,是否可以從內部類中訪問這個$ 0變量?或者它是隱藏的,只能通過反射變量獲得?此外,如何確定我是否在不使用字符串比較的情況下處理「$ 0」字段?希望在我的代碼中繼續執行if(field.getType()== classBeingProcessed.getClass()),但這顯然不再可行。我唯一的選擇是比較字符串嗎? –

+0

本教程出錯了。你可以在靜態上下文中有一個內部類(比如靜態方法),那麼它沒有包含實例。類的分類很混亂。 – irreputable