program tip

Class.newInstance ()가 "악"인 이유는 무엇입니까?

radiobox 2020. 9. 6. 09:18
반응형

Class.newInstance ()가 "악"인 이유는 무엇입니까?


Ryan DelucchiTom Hawtin 의 답변에 대한 의견 # 3에서 여기물었 습니다 .

Class.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 생성자에서 throw 된 모든 예외를 전파합니다. 이 메서드를 사용하면 컴파일러에서 수행 할 컴파일 타임 예외 검사를 효과적으로 우회 할 수 있습니다. Constructor.newInstance메서드는 생성자가 던진 예외를 (checked)에 래핑하여이 문제를 방지합니다 InvocationTargetException.

즉, 확인 된 예외 시스템을 무력화 할 수 있습니다.


또 다른 이유 :

최신 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
    }

이것을 호출하면 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원하지 않는 예외 처리를 우회합니다.

참고 URL : https://stackoverflow.com/questions/195321/why-is-class-newinstance-evil

반응형