Ryan Delucchi 要求 在这里, 在评论#3 汤姆Hawtin's的回答:

为什么是类。newInstance()"恶魔"?

这个响应的代码样本:

// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();

所以,为什么是恶魔吗?

有帮助吗?

解决方案

Java API文件解释了为什么(http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance()):

注意,这种方法传播的任何异常引发的nullary构造,包括经过检查的例外。使用这种方法有效地绕过的编写时间异常检查,否则将进行的编译器。的 Constructor.newInstance 方法避免了这个问题通过包装的任何异常引发通过该构造中(检查) InvocationTargetException.

换句话说,它可以打败的检查的例外情况的系统。

其他提示

一个原因:

现代的IDE让你找到类用途 - 它重构过程中有所帮助,如果您和您的IDE知道您计划什么是使用类代码更改

当你不这样做的构造函数的明确的使用,但使用Class.newInstance()来代替,你可能不会发现重构过程中使用,当你编译这个问题不会显现出来。

我不知道为什么没有人提供了一个简单的例子,基于解释这一点,相比Constructor::newInstance例如,由于最后Class::newInstance是由于Java-9。

假设你有一个非常简单的类(不要紧,它坏了):

static class Foo {
    public Foo() throws IOException {
        throw new IOException();
    }
}

和您尝试通过反射来创建它的一个实例。第一IOException

    Class<Foo> clazz = ...

    try {
        clazz.newInstance();
    } catch (InstantiationException e) {
        // handle 1
    } catch (IllegalAccessException e) {
        // handle 2
    }

调用,这将导致handle 1被抛出 - 问题是,你的代码不处理它,既不handle 2也不Constructor会抓住它。

在经由相反做,当它一<=>:

    Constructor<Foo> constructor = null;
    try {
        constructor = clazz.getConstructor();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }

    try {
        Foo foo = constructor.newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        System.out.println("handle 3 called");
        e.printStackTrace();
    }

这手柄3将被调用,因而你将处理它。

实际上,<=>绕过异常处理 - 你真的不想

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top