programing tip

IllegalStateException의 용도는 무엇입니까?

itbloger 2020. 10. 25. 11:44
반응형

IllegalStateException의 용도는 무엇입니까?


이것은 오늘 동료와의 토론에서 나왔습니다.

Java 용 Javadocs는 IllegalStateException다음과 같이 설명합니다.

메서드가 불법적이거나 부적절한 시간에 호출되었음을 알립니다. 즉, Java 환경 또는 Java 응용 프로그램이 요청 된 작업에 적합한 상태가 아닙니다.

효과적인 Java는 다음과 같이 말합니다 (항목 60, 페이지 248) :

일반적으로 재사용되는 또 다른 예외는 IllegalStateException입니다. 이것은 일반적으로 수신 객체의 상태로 인해 호출이 불법 인 경우 throw되는 예외입니다. 예를 들어, 호출자가 제대로 초기화되기 전에 일부 개체를 사용하려고 시도한 경우 throw되는 예외입니다.

여기에 약간의 불일치가있는 것 같습니다. javadocs의 두 번째 문장은 예외가 Java 실행 상태에 대한 매우 광범위한 조건을 설명 할 수있는 것처럼 들리지만, Effective Java의 설명은 특히 해당 객체의 상태와 관련된 조건에 사용되는 것처럼 들립니다. 메서드가 호출되었습니다.

JDK (예 : 컬렉션 Matcher) 및 Guava 에서 본 사용법 은 Effective Java가 말하는 범주에 해당하는 것 같습니다 ( "이 객체는이 메서드를 호출 할 수없는 상태에 있습니다"). 이것은 또한 IllegalStateException의 형제 와 일치하는 것 같습니다 IllegalArgumentException.

IllegalStateExceptionJDK에서 "Java 환경"또는 "Java 애플리케이션"과 관련된 합법적 인 사용이 있습니까? 아니면 더 광범위한 실행 상태에 사용하도록 권장하는 모범 사례 가이드가 있습니까? 그렇지 않다면 왜 도대체 javadocs가 그렇게 표현됩니까? ;)


다음은 JDK에서이 예외의 특히 합법적 인 사용입니다 (참조 : URLConnection.setIfModifiedSince(long)300 개 이상의 다른 사용 중 :

public void setIfModifiedSince(long ifmodifiedsince) {
    if (connected)
        throw new IllegalStateException("Already connected");
    ifModifiedSince = ifmodifiedsince;
}

예가 꽤 분명하다고 생각합니다. 개체가 특정 상태 ( " 이미 연결됨 ") 인 경우 일부 작업을 호출하면 안됩니다. 이 경우 연결이 설정되면 일부 속성을 설정할 수 없습니다.

이 예외는 클래스에 시간이 지남에 따라 변경되는 상태 (상태 머신?)가있어 일부 메서드가 관련이 없거나 불가능할 때 특히 유용합니다. 약 생각 Car이 클래스 start(), stop()fuel()방법. 차례로 start()두 번 전화하는 것은 잘못된 것이 아니지만 시동 된 차에 연료를 공급하는 것은 확실히 나쁜 생각입니다. 즉, 자동차가 잘못된 상태에 있습니다.

틀림없이 좋은 API는 우리가 잘못된 상태의 메서드를 호출하는 것을 허용하지 않아야합니다. 그래야 이런 문제가 런타임이 아닌 컴파일 타임에 발견됩니다. 이 특정 예제에서 URL에 연결하는 것은 연결 후 모두 유효한 메서드 하위 집합이있는 다른 개체를 반환해야합니다.


다음은 JDK의 예입니다. java.lang.Shutdown이라는 패키지 전용 클래스가 있습니다. 시스템이 종료되고 새 후크를 추가하려고하면 IllegalStateException이 발생합니다. 잘못된 상태에있는 Java 환경이기 때문에 이것이 "javadoc"지침의 기준을 충족한다고 주장 할 수 있습니다.

class Shutdown {    
...

   /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
    * but does not do any security checks.
    */
    static void add(int slot, Runnable hook) {
        synchronized (lock) {
            if (state > RUNNING)
                throw new IllegalStateException("Shutdown in progress");

            if (hooks[slot] != null)
                throw new InternalError("Shutdown hook at slot " + slot + " already registered");

            hooks[slot] = hook;
        }
    }

그러나 "javadoc"지침과 "Effective Java"지침간에 실제로 구분이 없음을 보여줍니다. Shutdown이 구현되는 방식 때문에 JVM의 종료 여부는 state라는 필드에 저장됩니다. 따라서 "state"필드가 수신 객체의 상태의 일부이기 때문에 IllegalStateException을 사용할시기에 대한 "Effective Java"지침도 충족합니다. 수신 오브젝트 (Shutdown)가 잘못된 상태이므로 IllegalStateException이 발생합니다.

제 생각에는 IllegalStateException을 사용할 때에 대한 두 가지 설명이 일관됩니다. 효과적인 자바 설명은 좀 더 실용적입니다. 우리 대부분에게 전체 Java 환경에서 가장 중요한 부분은 지금 작성중인 클래스이므로 작성자가 집중하고 있습니다.


나는 당신이 IllegalStateExceptionI의 사용법을 본다면 더 적절하다면 두 번째라고 말할 것입니다. 이 예외는 많은 패키지에서 사용됩니다.

  • java.net
  • java.nio
  • java.util
  • java.util.concurrrent 등

하나의 예제를 지정하기 위해 ArrayBlockingQueue.add 는 대기열이 이미 가득 찬 경우이 예외를 발생시킵니다. 이제 전체는 개체의 상태이며 부적절하거나 잘못된 시간에 호출되고 있습니다.

나는 둘 다 같지만 표현의 차이를 의미한다고 생각합니다.


도서관을 감안할 때, 그것은 던져해야 IllegalStateException하거나 IllegalArgumentException그것으로 인해 사용자 코드에 버그를 발견 할 때마다 라이브러리가 던져해야하는 반면, AssertionError이 버그를 발견 할 때마다 인한 라이브러리 자신의 구현에.

For example, in the library's tests, you may expect the library throws an IllegalStateException when the order of method calls are wrong. But you will never expect the library throws an AssertionError.


There is no 'discrepancy' here. There is nothing in Bloch's wording that excludes what it says in the JLS. Bloch is simply saying that if you have circumstance A, throw this exception. He is not saying that this exception is/should be thrown only in this condition. The JLS is saying this exception is thrown if A, B, or C.


I ran into this with:

try {
    MessageDigest digest = MessageDigest.getInstance("SHA-1");
    ...
} catch (NoSuchAlgorithmException e) {
    throw new AssertionError(e);
}

I think it will be impractical for me to throw IllegalStateException here in place of AssertionException even though this falls into the "the Java environment" category.

참고URL : https://stackoverflow.com/questions/12698275/whats-the-intended-use-of-illegalstateexception

반응형