Dims
Dims

Reputation: 50989

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.

Upvotes: 0

Views: 1728

Answers (4)

Ted Hopp
Ted Hopp

Reputation: 234795

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.

Upvotes: 1

Xavi López
Xavi López

Reputation: 27880

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.

Upvotes: 3

Péter Török
Péter Török

Reputation: 116246

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.

Upvotes: 7

aretai
aretai

Reputation: 1641

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?

Upvotes: 1

Related Questions