2013-03-27 47 views
0

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

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

应该我(为什么)写:

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

或:

MyInterface object = clazz.newInstance(); 

是否选择依赖于任我打算使用构造函数为空或需要参数?

回答

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. 

对不起编辑我的文章添加更多的引号,但这个解释比我更好。 Javadoc for Class.newInstance()对此进行了说明:

创建由此Class对象表示的类的新实例。该类被实例化,就像通过一个带有空参数列表的新表达式一样。如果该类尚未初始化,则该类将被初始化。

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

+0

我之前已经阅读过这个线程,并且觉得可以进一步讨论 - 欢迎使用“inline”示例! – Queequeg 2013-03-27 14:00:12

+0

请检查第二段:不应该是'Constructor'吗? – Queequeg 2013-03-27 14:06:18

+0

你是什么意思?我给出的例子是直接从第二个链接中获取的。 – 2013-03-27 14:25:24

0

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

在默认的构造(该一个不带任何参数)被调用

+0

但有很多发生在 – Queequeg 2013-03-27 13:56:17

+1

之间我更喜欢使用API​​文档作为指导,而不是任何实现。我经常见到IBM JDK的表现与Sun/Oracle JDK不同...... – mthmulders 2013-03-27 13:57:00

1

实施据newInstance()的Javadoc:

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

Appearantly,你可以使用newInstance()作为快捷方式

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

有但一个微妙的差异:Class#newInstance()将从ExceptionInInitializerError内部构造包裹的Excption,而Constructor#newInstance()将其包装内的InvocationTargetException

+0

所以我猜想,构造函数的使用更安全,因为它引发了一个'Exception'而不是'Error' .. – Queequeg 2013-03-27 13:57:42

+0

异常指示问题a程序_可能想catch_,而错误表示程序_不应该尝试catch_的问题。你的应用程序是否应该在这个动态调用的构造函数中捕获一个Exception取决于具体情况... – mthmulders 2013-03-27 14:08:15

0

clazz.newInstance()实际上试图抓住Constructor对象,所以它最终是相同的。

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

0

答案显而易见从javadoc的java.lang.Class

  • clazz.newInstance()方法仅适用于无参数构造函数。

  • clazz.getConstructor()等方法也适用于带参数的构造函数......只要您提供类型,然后提供构造函数参数的值。

如果你的用例只需要你使用无参数的构造函数,然后clazz.newInstance()是更简单的方法。

+0

更简单,但抛出一个错误:( – Queequeg 2013-03-27 14:05:06

相关问题