왜 class.newinstance ()“악”인 이유는 무엇입니까?
-
10-07-2019 - |
문제
라이언 델루 치 물었다 여기 주석 #3에서 Tom Hawtin답변 :
왜 class.newinstance () "Evil"인 이유는 무엇입니까?
코드 샘플에 대한 응답으로 :
// 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
방법은 생성자가 A (Checked)에서 던진 예외를 래핑 하여이 문제를 피합니다.InvocationTargetException
.
다시 말해, 확인 된 예외 시스템을 물리 칠 수 있습니다.
다른 팁
또 하나의 이유 :
Modern IDE를 사용하면 클래스 사용법을 찾을 수 있습니다. 리팩토링 중에 도움이됩니다. 귀하와 IDE가 변경하려는 클래스를 사용하는 코드를 알고 있다면 도움이됩니다.
생성자를 명시 적으로 사용하지는 않지만 Class.newinstance ()를 대신 사용하면 리팩토링 중에 사용량을 찾지 못하면이 문제는 컴파일 할 때 나타나지 않습니다.
나는 왜 아무도 이것에 대한 간단한 예제 기반 설명을 제공하지 않았는지 모르겠다. Constructor::newInstance
예를 들어, 그 이후로 마지막으로 Class::newInstance
Java-9 이후 더 이상 사용되지 않았습니다.
이 매우 간단한 클래스가 있다고 가정 해 봅시다.
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
}
이것을 호출하면 a IOException
던져진다 - 문제는 코드가 처리하지 않는다는 것입니다. handle 1
...도 아니다 handle 2
잡을 것입니다.
대조적으로 a 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
예외 처리를 우회합니다.