这个问题是关于 Java 的有趣行为:在某些情况下,它会为嵌套类生成额外的(非默认)构造函数。
这个问题也是关于奇怪的匿名类,Java 用那个奇怪的构造函数生成的。
考虑以下代码:
package a;
import java.lang.reflect.Constructor;
public class TestNested {
class A {
A() {
}
A(int a) {
}
}
public static void main(String[] args) {
Class<A> aClass = A.class;
for (Constructor c : aClass.getDeclaredConstructors()) {
System.out.println(c);
}
}
}
这将打印:
a.TestNested$A(a.TestNested)
a.TestNested$A(a.TestNested,int)
行。接下来,让构造函数A(int a)
私有:
private A(int a) {
}
再次运行程序。收到:
a.TestNested$A(a.TestNested)
private a.TestNested$A(a.TestNested,int)
它也可以。但是现在,让我们main()
以这种方式修改方法(添加新的类A
创建实例):
public static void main(String[] args) {
Class<A> aClass = A.class;
for (Constructor c : aClass.getDeclaredConstructors()) {
System.out.println(c);
}
A a = new TestNested().new A(123); // new line of code
}
然后输入变为:
a.TestNested$A(a.TestNested)
private a.TestNested$A(a.TestNested,int)
a.TestNested$A(a.TestNested,int,a.TestNested$1)
它是什么:a.TestNested$A(a.TestNested,int,a.TestNested$1) <<<---??
好的,让我们再次将构造函数A(int a)
包本地化:
A(int a) {
}
再次运行程序(我们不删除创建实例的行A
!),输出与第一次一样:
a.TestNested$A(a.TestNested)
a.TestNested$A(a.TestNested,int)
问题:
1)这怎么解释?
2)这第三个奇怪的构造函数是什么?
更新:调查显示如下。
1)让我们尝试使用来自其他类的反射来调用这个奇怪的构造函数。我们将无法做到这一点,因为没有任何方法可以创建那个奇怪TestNested$1
类的实例。
2)好的。让我们做的伎俩。让我们在类中添加TestNested
这样的静态字段:
public static Object object = new Object() {
public void print() {
System.out.println("sss");
}
};
好?好的,现在我们可以从另一个类中调用这第三个奇怪的构造函数:
TestNested tn = new TestNested();
TestNested.A a = (TestNested.A)TestNested.A.class.getDeclaredConstructors()[2].newInstance(tn, 123, TestNested.object);
对不起,但我完全不明白。
UPDATE-2:进一步的问题是:
3)为什么 Java 使用特殊的匿名内部类作为第三个合成构造函数的参数类型?为什么不只Object
键入具有特殊名称的构造函数?
4)什么Java可以使用已经定义的匿名内部类来实现这些目的?这不是某种违反安全的行为吗?