Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the access type of an anonymous inner class?

I've been thinking about classes, and specifically about anonymous inner classes. This led me to wonder what is the access type of an anonymous inner class?

I realize in most cases this won't change anything but it might make a difference for reflection for example. I've seen several questions asking about having problems using reflection to access the contents of anonymous inner classes.

I did find this question (one example of this problem): access exception when invoking method of an anonymous class using java reflection

And this answer which suggests it is private but the writer was unable to confirm: https://stackoverflow.com/a/2659647/3049628

like image 721
Tim B Avatar asked Nov 23 '15 13:11

Tim B


2 Answers

Looks like they are public, but the JDK's Method.invoke implementation has a (long-running) bug. See bug 4071957.

The linked bug does not really correspond to our situation, however it aggregates all types of Method.invoke access control problems over inner classes and was marked as duplicate of bug 4819108 which was linked in the accepted answer of the SO question you mentionned.

like image 97
Aaron Avatar answered Sep 26 '22 21:09

Aaron


The class itself seems to have package of outer class.

getModifiers() value is 8, which as per comments is: static, package private.

Its static (why ?). I can't refer to Main.this from inside of an anonymous class in Main.

Its package private. Still, access level of an anonymous class doesn't even mean much, since you can't use its type at compile time like a normal class.

https://ideone.com/vzbdQ5

// JDK 8
import java.lang.reflect.Modifier;

public class Main {
    public static void main(String[] args) throws Exception {
        Class anon = new Main() {}.getClass();

        System.out.println("Name:" + anon.getName()); // Main$1
        System.out.println("Anonymous:" + anon.isAnonymousClass()); // true
        System.out.println("Package:" + anon.getPackage()); // null

        System.out.println("public ? " + Modifier.isPublic(anon.getModifiers())); // false
        System.out.println("private ? " + Modifier.isPrivate(anon.getModifiers())); // false
        System.out.println("protected ? " + Modifier.isProtected(anon.getModifiers())); // false

        assert anon.newInstance() instanceof Main;
        assert Class.forName(anon.getName()).newInstance() instanceof Main;
    }
}
like image 21
S.D. Avatar answered Sep 23 '22 21:09

S.D.