是否可以使用 Java Reflection 创建内部类的实例?
代码示例:
public class Foo
{
public class Bar
{
public void printMesg(String body)
{
System.out.println(body);
}
}
public static void main(String[] args)
{
// Creating new instance of 'Bar' using Class.forname - how?
}
}
是否可以创建 Bar 类的新实例并给出其名称?我尝试使用:
Class c = Class.forName("Foo$Bar")
它找到了该类,但是当我使用 c.newInstance() 时,它会抛出 InstantiationException。
Sample of code:
public class Foo
{
public class Bar
{
public void printMesg(String body)
{
System.out.println(body);
}
}
public static void main(String[] args)
{
// Creating new instance of 'Bar' using Class.forname - how?
}
}
Is it possible to create new instance of class Bar giving its name? I tried to use:
Class c = Class.forName("Foo$Bar")
it finds the class, but when i use c.newInstance() it throws InstantiationException.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
你需要跳过一些障碍才能做到这一点。首先,您需要使用 Class.getConstructor() 查找要调用的
Constructor
对象:然后使用Constructor.newInstance():
You need to jump through a few hoops to do this. First, you need to use Class.getConstructor() to find the
Constructor
object you want to invoke:And then you use Constructor.newInstance():
如果不先构造父类,确实无法构造内部类。它不能存在于父类之外。进行反射时,您必须传递父类的实例。嵌套类是静态的,它们可以独立于父类使用,因此在进行反射时也是如此。
这是一个 SSCCE,它演示了所有内容。
这应该产生
Inner classes can indeed not be constructed without constructing the parent class first. It cannot exist outside the parent class. You'll have to pass an instance of the parent class in when doing reflection. Nested classes are
static
and they can be used independently from the parent class, thus also when doing reflection.Here's an SSCCE which demonstrates all the stuff.
This should produce
快速而肮脏的代码:
说明:您必须告诉 Bar 其封闭的 Foo。
Quick and dirty code:
Explanation: You must tell the Bar about its enclosing Foo.
是的。请记住,您需要将外部实例提供给内部类。使用 javap 查找构造函数。您将需要使用
java.lang.reflect.Constructor
,而不是依赖邪恶的Class.newInstance
。javap -c
对构造函数很有趣,因为(假设-target 1.4
或更高版本,现在是隐式的)您在调用超级构造函数之前会获得实例字段的赋值(用于是非法的)。Yes. Remember you need to feed the outer instance to an inner class. Use
javap
to find the constructor. You will need to go throughjava.lang.reflect.Constructor
rather than rely upon the evilClass.newInstance
.javap -c
is interesting on the constructor because (assuming-target 1.4
or later, now implicit) you get an assignment of an instance field before calling the super constructor (used to be illegal).其他答案已经解释了如何才能完成您想做的事情。
但我想向您建议,您需要这样做的事实表明您的系统设计有些问题。我建议您要么需要封闭类上的(非静态)工厂方法,要么需要将内部类声明为静态。
反射性地创建(非静态)内部类实例具有封装损坏的“气味”。
Other answers have explained how you can to what you want to do.
But I want to suggest to you that the fact that you need to do this at all is an indication that there is something a bit wrong with your system design. I would suggest that you either need a (non-static) factory method on the enclosing class, or you need to declare the inner class as static.
Creating a (non-static) inner class instance reflectively has a "smell" of broken encapsulation.
这并不完全是最佳的,但它适用于内部类和内部静态类的深度。
This isn't entirely optimal, but it works for depths of inner classes and inner static classes.
这是嵌套类(静态内部)的答案:
就我而言,我需要通过其完全限定名称获取类型,
“$”至关重要!
如果有一个点,你会得到类“package.innerClass.outerClass”的 ClassNotFoundException 异常。该异常具有误导性:-(。
Here a answer for nested class (static inner):
In my case i need to acquire the type by its fully qualified name
the '$' is crucial!
with a dot you'll get ClassNotFoundException for class "package.innerClass.outerClass". The exception is missleading :-(.