0

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

I need to access methods by reflection.

1
  • 1
    If its an anonymous inner class how would the compiler know where to look to call those methods? Why are you not just creating a public class and using it in the places you need to instead of using an anonymous class? Commented Mar 23, 2012 at 15:33

4 Answers 4

7

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.

Sign up to request clarification or add additional context in comments.

6 Comments

I disagree. The only difference between non-anonymous and anonymous inner classes is that latter ones have no name. The reason for this is brevity, not security. So the reason for anonymous classes can't be public is just the syntax was not proposed. IMHO.
+1 Not necessary to use the compiler-generated class name if you've got an instance, though (which is inherent to an anonymous inner class).
@XaviLópez, indeed. If you do have the instance, why do you need reflection?
We should definitely have some context on this matter to give a reasonable answer
@PéterTörök - You'd use reflection to gain access to methods declared in the anonymous class.
|
3

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.

Comments

1

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?

1 Comment

Anonymous inner classes have default (package private) access, not private.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.