2012-03-23 101 views
0

默認情況下,匿名內部類是否是私有的?我可以讓它們公開嗎?Java中的公共匿名內部類

我需要通過反射來訪問方法。

+1

如果它是一個匿名的內部類,編譯器將如何知道去哪裏調用這些方法?爲什麼你不只是創建一個公共類,並在你需要的地方使用它而不是使用匿名類? – jzworkman 2012-03-23 15:33:55

回答

2

您可以通過反射訪問匿名內部類的方法。請參閱getDeclaredMethods()。 請記得在Method上撥打setAccessible(true)以避免IllegalAccessException

Object testObject = new Object() { 
    private void testMe() { 
     System.out.println("testme"); 
    } 
}; 
Method m = testObject.getClass().getDeclaredMethod("testMe"); 
m.setAccessible(true); 
m.invoke(testObject); // prints out "testme" 

還要注意,如果有一個SecurityManager這將是不可能的,看到What is the security risk of object reflection?

警告:要考慮到匿名內部類是一種一次性類定義。一旦使用,你再也不需要他們了。就像@PéterTörök所說,沒有更多關於你的問題的背景很難說清楚,但是,如果你能控制這個類,那麼可能會更好地對這個類進行匿名化(使私人內部類,甚至公開),並將該方法公開給需要它的類。

7

由於某種原因,匿名內部類是匿名的:它們並不意味着只能通過引用變量/方法參數從外部世界直接訪問。 (出於同樣的原因,他們都是私人了。)

我猜你可以嘗試使用它的編譯器生成的名稱(例如,OuterClass$1)通過反射來訪問這樣的一類,但是,這種爲特定實現,可能會改變當您將另一個匿名內部類添加到相同的外部類或下一個JVM版本時。所以這樣的解決方案會非常脆弱。

你爲什麼要這麼做?如果你解釋你的實際問題,我們可能會提供一個更好的選擇。

+0

我不同意。非匿名內部類和匿名內部類之間的唯一區別是後者沒有名稱。其原因是簡潔,而不是安全。所以匿名類的原因不能被公開只是沒有提出的語法。恕我直言。 – Dims 2012-03-23 16:07:17

+0

+1雖然(這是匿名內部類固有的),但如果您擁有實例,則不需要使用編譯器生成的類名稱。 – 2012-03-23 16:10:11

+0

@XaviLópez的確如此。如果你確實有實例,爲什麼你需要反思? – 2012-03-23 16:14:57

1

匿名內部類具有包私人(默認)訪問。在Java 6中,如果在靜態上下文中聲明它們,但在其他上下文中不是最終的,則它們是最終的。 (我相信,但還沒有測試,這在Java 7中已經更改,因此他們總是最終,見Section 15.9.5 of the Java Language Specification

例如,這個類有四個匿名內部類:

public class InnerTest { 
    public Runnable foo1 = new Runnable() { 
     public void run() {foo1();} 
     void foo1() {} 
    }; 
    private Runnable foo2 = new Runnable() { 
     public void run() {foo2();} 
     void foo2() {} 
    }; 
    public static Runnable foo3 = new Runnable() { 
     public void run() {foo3();} 
     void foo3() {} 
    }; 
    private static Runnable foo4 = new Runnable() { 
     public void run() {foo4();} 
     void foo4() {} 
    }; 
} 

當使用javac編譯(版本1.6.0_26)它會生成四個匿名內部類。反編譯與javap -c顯示:

  • InnerTest$1foo1)—包私人
  • InnerTest$2foo2)—包私人
  • InnerTest$3foo3)—包私人和最終
  • InnerTest$4foo4)—包專用並且最終

注意,其中匿名內部類的實例是被分配的變量訪問是無關緊要的。