当前位置:  开发笔记 > 编程语言 > 正文

为什么Class.newInstance()"邪恶"?

如何解决《为什么Class.newInstance()"邪恶"?》经验,为你挑选了3个好方法。

瑞安DELUCCHI问这里的评论#3 汤姆Hawtin的回答是:

为什么Class.newInstance()"邪恶"?

这是为了响应代码示例:

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

那么,为什么它是邪恶的?



1> Chris Jester..:

Java API文档解释了原因(http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance()):

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

换句话说,它可以击败已检查的例外系统.


@Ryan:那不是真的; 所有其他基于反射的调用方法抛出一个名为`InvocationTargetException`的已检查异常,该异常包装被调用方法抛出的任何throwable.`Class.newInstance`不会这样做 - 它将直接抛出已检查的异常.缺点是javac也不会让你试图捕获这些异常,因为没有声明`Class.newInstance`抛出它们.
这一般是反射的本质......根本不是特定于Constructor.newInstance().

2> alexei.vidmi..:

还有一个原因:

现代IDE允许您查找类用法 - 如果您和您的IDE知道哪些代码正在使用您计划更改的类,则它在重构期间会有所帮助.

如果不明确使用构造函数,而是使用Class.newInstance(),则可能无法在重构期间找到该用法,并且在编译时此问题不会显现.


也是使用反射的一般方法.

3> Eugene..:

我不知道为什么没有人提供一个简单的基于例子的解释,Constructor::newInstance例如,因为自从java-9 以来最终 Class::newInstance被弃用.

假设你有这个非常简单的类(无论它是否被破坏):

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

并且您尝试通过反射创建它的实例.第一Class::newInstance:

    Class clazz = ...

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

调用它会导致IOException抛出 - 问题是你的代码没有处理它,既handle 1不会也handle 2不会捕获它.

相比之下,通过以下方式进行Constructor:

    Constructor 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,因此您将处理它.

实际上,Class::newInstance绕过了异常处理 - 你真的不想要它.

推荐阅读
乐韵答题
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有