2013-05-10 93 views
2

Java允許您在匿名類中聲明新字段,但我無法弄清楚如何從外部訪問它們,即使將它們設置爲public也不會讓我知道。如何訪問匿名對象中聲明的字段?

class A { 
    public static void main(String[] args) { 
     Object o = new Object() { 
      public int x = 0; 
      { 
       System.out.println("x: " + x++); 
       System.out.println("x: " + x++); 
      } 
     }; 
     System.out.println(o.x); 
    } 
} 

我得到這個編譯器錯誤:

$ javac A.java && java A 
A.java:10: cannot find symbol 
symbol : variable x 
location: class java.lang.Object 
     System.out.println(o.x); 
         ^
1 error 

爲什麼?

+0

這AINT JavaScript的人:?d – 2013-05-10 23:59:19

回答

6

Why?

這是因爲Object是靜態類型變量o,並Object沒有財產x。下面無法編譯的確切同樣的原因:

public class X { 
    public int x; 

    public static void main(String[] args) { 
    Object o = new X(); 
    o.x = 3; 
    } 
} 

我們希望,您的Java的直覺是正確的這個例子中,你希望這個失敗。所以把這個直覺移植到你的例子中。

How to access fields declared inside anonymous object?

與我在示例中使用x的方式相同:反射。

Object o = new X(); 
o.getClass().getField("x").setInt(o, 3); 

Why does it let me make public fields if I can't use them?

如果沒有讓你做公共領域,甚至反射也不會爲你工作,至少不會像如上簡單。

3

你只能通過反射來做到這一點。班級沒有名字,所以你必須聲明變量oObject,而Object沒有該成員。換句話說,不要這樣做

+0

然後howcome未使用的變量是一個編譯錯誤,它更容易不禁止那些尚未Java那樣它 – Dog 2013-05-10 20:50:29

+0

未使用的變量是*不*由Java語言規範編譯錯誤是什麼。一個IDE被配置爲報告爲一個沒有任何錯誤與Java語言相關。 – 2013-05-10 21:19:07

+0

@MarkoTopolnik,糟糕。我的意思是,無法訪問的代碼行會導致編譯錯誤。而且不容易擁有類型,所以我不會認爲Java只是因爲實現起來更容易,而只是做一些事情。 – Dog 2013-05-10 22:27:48

1

您可以通過反射存取權限領域:

Object o = new Object() { 
     public int x = 0; 
     { 
      System.out.println("x: " + x++); 
      System.out.println("x: " + x++); 
     } 
    }; 
    System.out.println(o.getClass().getField("x").get(o)); 

更好的風格應該是命名類,並把它作爲變量類型,如果你想訪問現場:

class MyObject { 
     public int x = 0; 
     { 
      System.out.println("x: " + x++); 
      System.out.println("x: " + x++); 
     } 
    } 
    MyObject o = new MyObject(); 
    System.out.println(o.x); 
1

你可以直接訪問它的匿名類創建表達式:

class A { 
    public static void main(String[] args) { 
     System.out.println(new Object() { 
      public int x = 0; 
      { 
       System.out.println("x: " + x++); 
       System.out.println("x: " + x++); 
      } 
     }.x); 
    } 
} 

但是,然後,你不能使用obj ect創建了,所以它有點沒用。

0

限定延伸Object(在特定情況下,一個內部類,你不應該寫extends Object,因爲它是無論如何做在你的類,定義字段,不是由你的類型的引用來訪問他們

。例如:

void func() { 
    class MyInt extends Integer { 
     boolean isSane = true; 
    } 
    MyInt intInstance = new MyInt(); 
    if (intInstance .isSane) { 
     System.out.println("sane integer"); 
    } 
}