简体   繁体   English

Java中的公共匿名内部类

[英]public anonymous inner class in Java

Are anonymous inner classes private by default? 默认情况下,匿名内部类是否为私有? Can I make them public? 我可以将它们公开吗?

I need to access methods by reflection. 我需要通过反射访问方法。

Anonymous inner classes are anonymous for a reason: they aren't meant to be accessed directly from the outside world, only via a referring variable / method parameter. 匿名内部类之所以是匿名的,是因为其原因:它们并不意味着只能通过引用变量/方法参数直接从外部访问。 (And for the same reason, they are private too.) (出于同样的原因,它们也是私有的。)

I guess you may try to access such a class via reflection using its compiler-generated name (eg OuterClass$1 ), however that is implementation specific and may change the moment you add another anonymous inner class to the same outer class, or in the next JVM version. 我猜您可能会尝试使用其编译器生成的名称(例如, OuterClass$1 )通过反射来访问此类,但是这是实现特定的,可能会在您将另一个匿名内部类添加到同一外部类时或在下一个外部类中更改JVM版本。 So such a solution would be very brittle. 因此,这样的解决方案将非常脆弱。

Why would you actually want to do this? 您实际上为什么要这样做? If you explain your actual problem, we may be able to offer a better alternative. 如果您解释了您的实际问题,我们也许可以提供更好的选择。

You can access an anonymous inner class' methods with reflection. 您可以通过反射访问匿名内部类的方法。 See getDeclaredMethods() . 请参见getDeclaredMethods() Remember to call setAccessible(true) on the Method in order to avoid an IllegalAccessException . 请记住在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"

Also notice that if there's a SecurityManager this won't be possible, see What is the security risk of object reflection? 另请注意,如果没有SecurityManager将无法实现,请参阅对象反射的安全风险是什么?

Warning: Take into account that anonymous inner classes are kind of disposable class definitions. 警告:请考虑到匿名内部类是一次性类的定义。 Once used, you'll never need them elsewhere again. 一旦使用,您将再也不需要它们了。 Just like @PéterTörök said, it's hard to tell without more context on your problem, but, if you've got control over that class, it would probably be better to deanonymize that class (making a private inner class, or even public), and expose that method to the classes that need it. 就像@PéterTörök所说的那样,要在没有更多关于您的问题的上下文的情况下很难说,但是,如果您可以控制该类,则最好对该类取消匿名(将其设为私有内部类,甚至公开),并将该方法公开给需要它的类。

Anonymous inner classes are private by default. 默认情况下,匿名内部类是私有的。 For use with reflection you can have a look here - Java reflection: How can I retrieve anonymous inner classes? 要与反射一起使用,您可以在这里查看-Java反射:如何检索匿名内部类?

Anonymous inner classes have package private (default) access. 匿名内部类具有程序包私有(默认)访问权限。 In Java 6, they are final if declared in a static context but not final in other contexts. 在Java 6中,如果在静态上下文中声明它们,则为final,但在其他上下文中声明为final。 (I believe, but have not tested, that this has changed in Java 7 so that they are always final; see Section 15.9.5 of the Java Language Specification .) (我相信但尚未测试,Java 7中已对此进行了更改,因此它们始终是最终版本;请参阅Java语言规范的15.9.5节 。)

For example, this class has four anonymous inner classes: 例如,此类有四个匿名内部类:

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() {}
    };
}

When compiled with javac (version 1.6.0_26) it generates four anonymous inner classes. 使用javac(版本1.6.0_26)进行编译时,它将生成四个匿名内部类。 Decompiling with javap -c reveals: 使用javap -c反编译显示:

  • InnerTest$1 ( foo1 ) — package private InnerTest$1foo1 )—私有程序包
  • InnerTest$2 ( foo2 ) — package private InnerTest$2foo2 )—私有程序包
  • InnerTest$3 ( foo3 ) — package private and final InnerTest$3foo3 )—私有和最终打包
  • InnerTest$4 ( foo4 ) — package private and final InnerTest$4foo4 )—私有和最终打包

Note that the access of the variable to which the anonymous inner class instance is being assigned is irrelevant. 注意,匿名内部类实例所分配到的变量的访问是无关紧要的。

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

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