Issue with constructors of nested class

前端 未结 2 1499
挽巷
挽巷 2020-12-14 10:03

This question is about interesting behavior of Java: it produces additional (not default) constructor for nested classes in some situations.

2条回答
  •  囚心锁ツ
    2020-12-14 10:46

    The third constructor is a synthetic constructor generated by the compiler, in order to allow access to the private constructor from the outer class. This is because inner classes (and their enclosing classes' access to their private members) only exist for the Java language and not the JVM, so the compiler has to bridge the gap behind the scenes.

    Reflection will tell you if a member is synthetic:

    for (Constructor c : aClass.getDeclaredConstructors()) {
        System.out.println(c + " " + c.isSynthetic());
    }
    

    This prints:

    a.TestNested$A(a.TestNested) false
    private a.TestNested$A(a.TestNested,int) false
    a.TestNested$A(a.TestNested,int,a.TestNested$1) true
    

    See this post for further discussion: Eclipse warning about synthetic accessor for private static nested classes in Java?

    EDIT: interestingly, the eclipse compiler does it differently than javac. When using eclipse, it adds an argument of the type of the inner class itself:

    a.TestNested$A(a.TestNested) false
    private a.TestNested$A(a.TestNested,int) false
    a.TestNested$A(a.TestNested,int,a.TestNested$A) true
    

    I tried to trip it up by exposing that constructor ahead of time:

    class A {    
        A() {
        }   
    
        private A(int a) {
        }
    
        A(int a, A another) { }
    }
    

    It dealt with this by simply adding another argument to the synthetic constructor:

    a.TestNested$A(a.TestNested) false
    private a.TestNested$A(a.TestNested,int) false
    a.TestNested$A(a.TestNested,int,a.TestNested$A) false
    a.TestNested$A(a.TestNested,int,a.TestNested$A,a.TestNested$A) true
    

提交回复
热议问题