개인 유틸리티 클래스 생성자에서 사용할 수있는 선호하는 것은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/398953

  •  29-08-2019
  •  | 
  •  

문제

효과적인 Java (제 2 판), 항목 4에서는 개인 생성자를 사용하여 비 임계성을 시행하는 것에 대해 논의합니다. 다음은 책의 코드 샘플입니다.

public final class UtilityClass {
    private UtilityClass() {
        throw new AssertionError();
    }
}

하지만, AssertionError 던질 옳은 것 같지 않습니다. API가 사용을 정의하는 방법입니다. AssertionError.

다른 것이 있습니까? Throwable 그것은 일반적 으로이 상황에 있습니까? 일반적으로 장군을 던지는 사람이 있습니다 Exception 메시지로? 아니면 관습을 작성하는 것이 일반적입니까? Exception 이것을 위해?

그것은 꽤 사소하지만, 나는 스타일과 표준 관점에서 그것에 대해 궁금한 점이 있다고 생각합니다.

도움이 되었습니까?

해결책

"이 생성자가 결코 호출되지 않을 것이라고 주장하고있다"고 주장이있다. 그래서 실제로, AssertionError 여기에 맞습니다.

다른 팁

나는 Bloch의 의견을 포함하는 것을 좋아합니다.

// Suppress default constructor for noninstantiability

또는 더 나은 아직 오류에 넣습니다.

private UtilityClass()
{
    throw new AssertionError("Suppress default constructor for noninstantiability");
}

UnsupportedOperationException 확인 된 예외는 더 나을 것이지만 컴파일 타임에 클래스를 잘못 인스턴스화하는 사람에게 경고 할 수 있기 때문에 확인 된 예외는 더 좋습니다.

는 어때 불법 세저러 ? :)

아니요 아니요, 조쉬 블로 치 (Josh Bloch)에 대한 모든 것을 존중합니다. 절대 던지지 마십시오 AssertionError 주장에서 나오지 않는 한. 여기에 AssertionError를 원한다면 assert(false). 그런 다음 코드를 읽는 사람이 나중에 찾을 수 있습니다.

더 좋은 점은 자신의 예외를 정의하십시오 CantInstantiateUtilityClass. 그러면 당신은 말하는 코드가 있습니다

try {
    // some stuff
} catch (CantInstantiateUtilityClass e) {
    // react
}

포수의 독자가 알고 있습니다 무엇 일어난.

업데이트

너무나도 바보가 여기에 의해 방황하고 사실 이후 거의 4 년 후에 이것을 다시 내리게합니다. 따라서 표준에 주목하겠습니다 아직 정의합니다 AssertionError 실패한 주장의 결과로 일부 초보자가 생각하는 것이 아니라 잘 정의 된 유익한 예외 대신에 버려야합니다. 안타깝게도, 좋은 예외 징계는 아마도 Java 프로그래밍에서 가장 장려 된 기술 일 것입니다.

코드가 Maven 테스트 범위 내에서와 같은 종속성으로 주니트를 포함시킬 필요가있는 경우 <scope>test</scope>, 곧바로 가십시오 Assertion.fail() 방법과 명확성이 크게 향상되어 이익을 얻습니다.

public final class UtilityClass {
    private UtilityClass() {
        fail("The UtilityClass methods should be accessed statically");
    }
}

테스트 범위를 벗어난 경우 위와 같이 정적 가져 오기가 필요한 다음과 같은 것을 사용할 수 있습니다. import static pkg.Error.fail;

public class Error {
    private static final Logger LOG = LoggerFactory.getLogger(Error.class);
    public static void fail(final String message) {
        LOG.error(message);
        throw new AssertionError(message);
        // or use your preferred exception 
        // e.g InstantiationException
    }
}

다음 사용량.

public class UtilityClassTwo {
    private UtilityClassTwo() {
        Error.fail("The UtilityClass methods should be accessed statically");
    }
}

가장 관용적 인 형태로, 그들은 모두 이것으로 요약됩니다.

public class UtilityClassThree {
    private UtilityClassThree() {
        assert false : "The UtilityClass methods should be accessed statically";
    }
}

내장 예외 중 하나 인 UnsupportEdoperationException을 통해 '요청 된 작업이 지원되지 않는다'는 것을 나타낼 수 있습니다.

 private Constructor() {
    throw new UnsupportedOperationException(
            "Do not instantiate this class, use statically.");
}

깨진 주장은 코드의 계약 사양을 끊었다는 것을 의미합니다. 그래서 여기가 옳은 일입니다.

그러나 인스턴스를 개인적으로 인스턴스화한다고 가정하면 다른 생성자가없는 한 생성자를 호출하고 오류가 발생합니까?

자신만의 클래스 확장을 만들 수 있습니다 Throwable, EG :

class NoninstantiabilityError extends Throwable

여기에는 다음과 같은 장점이 있습니다.

  • 이름은 문제를 나타냅니다
  • 직접 확장되기 때문입니다 Throwable 우연히 잡힐 것 같지는 않습니다.
  • 직접 확장되기 때문입니다 Throwable 우연히 확인하고 각 생성자에게 전화를 걸어 예외를 잡아야합니다.

사용 예 :

public final class UtilityClass {
    private UtilityClass() throws NoninstantiabilityError {
        throw new NoninstantiabilityError();
    }

    ...
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top