繁体   English   中英

Java中的公共匿名内部类

[英]public anonymous inner class in Java

默认情况下,匿名内部类是否为私有? 我可以将它们公开吗?

我需要通过反射访问方法。

匿名内部类之所以是匿名的,是因为其原因:它们并不意味着只能通过引用变量/方法参数直接从外部访问。 (出于同样的原因,它们也是私有的。)

我猜您可能会尝试使用其编译器生成的名称(例如, OuterClass$1 )通过反射来访问此类,但是这是实现特定的,可能会在您将另一个匿名内部类添加到同一外部类时或在下一个外部类中更改JVM版本。 因此,这样的解决方案将非常脆弱。

您实际上为什么要这样做? 如果您解释了您的实际问题,我们也许可以提供更好的选择。

您可以通过反射访问匿名内部类的方法。 请参见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将无法实现,请参阅对象反射的安全风险是什么?

警告:请考虑到匿名内部类是一次性类的定义。 一旦使用,您将再也不需要它们了。 就像@PéterTörök所说的那样,要在没有更多关于您的问题的上下文的情况下很难说,但是,如果您可以控制该类,则最好对该类取消匿名(将其设为私有内部类,甚至公开),并将该方法公开给需要它的类。

默认情况下,匿名内部类是私有的。 要与反射一起使用,您可以在这里查看-Java反射:如何检索匿名内部类?

匿名内部类具有程序包私有(默认)访问权限。 在Java 6中,如果在静态上下文中声明它们,则为final,但在其他上下文中声明为final。 (我相信但尚未测试,Java 7中已对此进行了更改,因此它们始终是最终版本;请参阅Java语言规范的15.9.5节 。)

例如,此类有四个匿名内部类:

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 )—私有和最终打包

注意,匿名内部类实例所分配到的变量的访问是无关紧要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM