为什么 Class.newInstance() 是“邪恶的”?
Ryan Delucchi询问这里在评论#3中给Tom霍廷的回答:
为什么 Class.newInstance() 是“邪恶的”?
这是对代码示例的回应:
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
那么,为什么它是邪恶的?
Ryan Delucchi asked here in comment #3 to Tom Hawtin's answer:
why is Class.newInstance() "evil"?
this in response to the code sample:
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
so, why is it Evil?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Java API 文档解释了原因 (http: //java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance()):
换句话说,它可以击败检查异常系统。
The Java API documentation explains why (http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance()):
In other words, it can defeat the checked exceptions system.
还有一个原因:
现代 IDE 允许您查找类的用法 - 如果您和您的 IDE 知道哪些代码正在使用您计划更改的类,那么它会在重构过程中有所帮助。
当您不显式使用构造函数,而是使用 Class.newInstance() 时,您可能会在重构期间找不到该用法,并且在编译时不会出现此问题。
One more reason:
Modern IDEs allow you to find class usages - it helps during refactoring, if you and your IDE know what code is using class that you plan to change.
When you don't do an explicit usage of the constructor, but use Class.newInstance() instead, you risk not to find that usage during refactoring and this problem will not manifest itself when you compile.
我不知道为什么没有人对此提供一个简单的基于示例的解释,例如与
Constructor::newInstance
相比,因为 finallyClass::newInstance
自 java-9 起已被弃用。假设您有一个非常简单的类(它被破坏并不重要):
并且您尝试通过反射创建它的实例。 第一个
Class::newInstance
:调用此函数将导致抛出
IOException
- 问题是您的代码不处理它,也不handle 1
handle 2
也无法捕获它。相反,当通过构造函数执行此操作时:
将调用句柄 3,因此您将处理它。
实际上,
Class::newInstance
绕过了异常处理 - 这是您真正不想要的。I don't know why no one provided a simple example based explanation to this, as compared to
Constructor::newInstance
for example, since finallyClass::newInstance
was deprecated since java-9.Suppose you have this very simple class (does not matter that it is broken):
And you try to create an instance of it via reflection. First
Class::newInstance
:Calling this will result in a
IOException
being thrown - problem is that your code does not handle it, neitherhandle 1
norhandle 2
will catch it.In contrast when doing it via a
Constructor
:that handle 3 will be called, thus you will handle it.
Effectively,
Class::newInstance
bypasses the exception handling - which you really don't want.