Reputation: 50989
Are anonymous inner classes private by default? Can I make them public?
I need to access methods by reflection.
Upvotes: 0
Views: 1728
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 privateInnerTest$2
(foo2
) — package privateInnerTest$3
(foo3
) — package private and finalInnerTest$4
(foo4
) — package private and finalNote that the access of the variable to which the anonymous inner class instance is being assigned is irrelevant.
Upvotes: 1
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
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
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