为什么获取构造函数对象而不是直接创建实例?

时间:2013-03-27 13:49:25

标签: java reflection

有:

Class<? extends MyInterface> clazz = ...;

我应该(以及为什么)写:

Constructor<? extends MyInterface> ctor = clazz.getConstructor();
MyInterface object = ctor.newInstance();

或:

MyInterface object = clazz.newInstance();

选择是否取决于我打算使用的构造函数是空的还是带参数?

5 个答案:

答案 0 :(得分:1)

根据newInstance()的Javadoc:

  

该类被实例化,就好像是一个带有空参数列表的新表达式。如果尚未初始化,则初始化该类。

显然,您可以使用newInstance()作为

的快捷方式
Constructor<? extends MyInterface> ctor = clazz.getConstructor();
MyInterface object = ctor.newInstance();

但是有一个细微的差别:Class#newInstance()将一个Excption从ExceptionInInitializerError内的构造函数中包装起来,而Constructor#newInstance()将它包装在InvocationTargetException中。

答案 1 :(得分:1)

看看这个similar questionThis链接还提供了更多示例和更详细的说明。

To sum up the arguments (from the second link):

    Class.newInstance() can only invoke the zero-argument constructor, 
    while Constructor.newInstance() may invoke any constructor, regardless 
    of the number of parameters.

    Class.newInstance() throws any exception thrown by the constructor, 
    regardless of whether it is checked or unchecked. 

    Class.newInstance() requires that the constructor be visible;  
    Constructor.newInstance() may invoke private constructors under certain 
    circumstances.

很抱歉编辑我的帖子以添加更多报价,但这解释得比我更好。 Class.newInstance()的Javadoc解释如下:

创建此Class对象表示的类的新实例。该类实例化为具有空参数列表的新表达式。如果尚未初始化,则初始化该类。

请注意,此方法传播由nullary构造函数抛出的任何异常,包括已检查的异常。使用此方法可以有效地绕过编译时异常检查,否则将由编译器执行。 Constructor.newInstance方法通过在(已检查的)InvocationTargetException中包装构造函数抛出的任何异常来避免此问题。

答案 2 :(得分:0)

根据源代码of java.lang.Class Class.newInstance()Constructor.newInstance()

相同

在实现中,调用默认构造函数(没有任何参数的构造函数)

答案 3 :(得分:0)

clazz.newInstance()实际上试图获取Constructor对象,因此它最终都是相同的。

第一种语法允许使用带有args的构造函数实例化类。

答案 4 :(得分:0)

通过彻底阅读java.lang.Class的javadoc,答案是显而易见的。

  • clazz.newInstance()方法仅适用于no-args构造函数。

  • clazz.getConstructor()等方法也适用于带参数的构造函数...前提是您提供构造函数参数的类型和值。

如果您的用例仅要求您使用no-args构造函数,则clazz.newInstance()是更简单的方法。