我想了解为什么以下内容不起作用:
public class HelloClass {
private class MyClass
{
public MyClass()
{
System.out.println ("Oh heck this is me!");
}
}
public Object newInstance (Object o)
{
try {
// java.lang.InstantiationException here
return o.getClass().newInstance();
} catch (Exception e) {
e.printStackTrace(System.out);
return null;
}
}
public void run()
{
MyClass m = new MyClass();
Object o = newInstance(m);
}
public static void main(String[] args)
{
HelloClass hd = new HelloClass();
hd.run();
}
}
我知道通过将newInstance参数声明为Class< T>来实现此目的的正确方法,但是想要理解为什么它不能像上面那样完成。
UPD:这是我得到的例外:
java.lang.InstantiationException: HelloClass$MyClass
at java.lang.Class.newInstance0(Class.java:340)
at java.lang.Class.newInstance(Class.java:308)
at HelloClass.newInstance(HelloClass.java:14)
at HelloClass.run(HelloClass.java:24)
at HelloClass.main(HelloClass.java:30)
答案 0 :(得分:6)
内部类的构造函数有一个隐藏的第一个参数,您需要在使用反射时提供该参数。传递外部类的实例。
而不是
return o.getClass().newInstance();
使用:
return o.getClass().getConstructor(getClass()).newInstance(this);
答案 1 :(得分:1)
问题似乎是它是一个非静态成员类,因为如果你将MyClass
声明为静态并且你将它设为顶级类,它就可以工作。但不太清楚为什么会这样。
答案 2 :(得分:1)
非常好的问题!
这是因为内部类在每个构造函数中都有一个隐式参数 - 它的外部类。因此它没有默认构造函数。
要获取它的实例,必须通过将外部类作为参数传递来实例化它。
Constructor constructor = o.getClass().getConstructor(HelloClass.class);
return constructor.newInstance(this);
答案 3 :(得分:0)
Class对象中的newInstance方法仅适用于具有no-arg构造函数的具体类。
如果您将MyClass更改为静态,它将符合条件并且代码可以正常工作。实际上,它有一个隐式构造函数,外部对象作为参数,没有no-arg构造函数。
您可以使用构造函数的newInstance方法使您自己的newInstance方法工作:
public Object newInstance (Object o)
{
try {
final Constructor<? extends Object> constructor =
o.getClass().getConstructor(this.getClass());
return constructor.newInstance(this);
} catch (Exception e) {
e.printStackTrace(System.out);
return null;
}
}