为了账号安全,请及时绑定邮箱和手机立即绑定

为什么Class.newInstance()是“邪恶的”?

为什么Class.newInstance()是“邪恶的”?

德玛西亚99 2019-11-12 12:52:35
瑞安DELUCCHI问这里的评论#3 汤姆Hawtin的回答是:为什么Class.newInstance()是“邪恶的”?这是对代码示例的响应:// Avoid Class.newInstance, for it is evil.Constructor<? extends Runnable> ctor = runClass.getConstructor();Runnable doRun = ctor.newInstance();那么,为什么是邪恶的?
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

另一个原因:

现代化的IDE允许您查找类的用法-如果您和您的IDE知道正在使用什么代码打算使用要更改的类,则它在重构过程中会有所帮助。

如果不对构造函数进行显式使用,而是改用Class.newInstance(),则可能会在重构过程中找不到这种用法,并且在编译时不会出现此问题。


查看完整回答
反对 回复 2019-11-12
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

我不知道为什么没有人对此提供基于示例的简单解释,Constructor::newInstance例如,自从java-9 以来终于 Class::newInstance被弃用了。


假设您有一个非常简单的类(与它是否损坏无关):


static class Foo {

    public Foo() throws IOException {

        throw new IOException();

    }

}

您尝试通过反射创建它的实例。首先Class::newInstance:


    Class<Foo> clazz = ...


    try {

        clazz.newInstance();

    } catch (InstantiationException e) {

        // handle 1

    } catch (IllegalAccessException e) {

        // handle 2

    }

调用它会导致IOException被抛出-问题是您的代码无法处理它,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将被调用,因此您将对其进行处理。


有效地,Class::newInstance绕过了异常处理-您真正不想要的。


查看完整回答
反对 回复 2019-11-12
  • 3 回答
  • 0 关注
  • 2183 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信