Question

Are anonymous inner classes private by default? Can I make them public?

I need to access methods by reflection.

Was it helpful?

Solution

You can access an anonymous inner class' methods with reflection. See getDeclaredMethods(). Remember to call setAccessible(true) on the Method in order to avoid an 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?

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.

OTHER TIPS

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 (e.g. 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. 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.

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?

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. (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.)

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. Decompiling with javap -c reveals:

  • InnerTest$1 (foo1) — package private
  • InnerTest$2 (foo2) — package private
  • InnerTest$3 (foo3) — package private and final
  • InnerTest$4 (foo4) — package private and final

Note that the access of the variable to which the anonymous inner class instance is being assigned is irrelevant.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top