[java] 스위치에서 null을 사용하는 방법

Integer i = ...

switch (i){
    case null:
        doSomething0();
        break;
    }

위의 코드에서 switch case 문에 null을 사용할 수 없습니다. 어떻게 다르게 할 수 있습니까? default다른 것을하고 싶기 때문에 사용할 수 없습니다 .



답변

switchJava 의 명령문에서는 불가능합니다 . 확인하기 null전에 switch:

if (i == null) {
    doSomething0();
} else {
    switch (i) {
    case 1:
        // ...
        break;
    }
}

switch명령문 *에 임의의 객체를 사용할 수 없습니다 . 컴파일러가 switch (i)어디에 있는지 i에 대해 불만을 제기하지 않는 이유 Integer는 Java가에서 Integerto를 자동으로 개봉하기 때문 int입니다. assylias가 이미 말했듯이, unboxing은 NullPointerException때 를 던질 것 i입니다 null.

* Java 7부터 명령문 String에서 사용할 수 있습니다 switch.

Oracle Docs-Switch의 자세한 내용 switch(널 변수가 포함 된 예 포함)


답변

switch ((i != null) ? i : DEFAULT_VALUE) {
        //...
}


답변

switch(i)내가 경우 NullPointerException이 발생합니다 null가를 언 박싱하려고하기 때문에, Integerint. 따라서 case null불법적 인 것은 어쨌든 결코 도달하지 못했을 것입니다.

switch명령문 앞에 i가 널이 아닌지 확인해야 합니다.


답변

Java 문서는 분명히 다음과 같이 말했습니다.

스위치 레이블로 null을 사용하는 것을 금지하면 실행할 수없는 코드를 작성할 수 없습니다. 스위치식이 박스형 기본 형식 또는 열거 형과 같은 참조 형식 인 경우식이 런타임에서 null로 평가되면 런타임 오류가 발생합니다.

Swithch 문을 실행하기 전에 null을 확인해야합니다.

if (i == null)

스위치 문을 참조하십시오

case null: // will never be executed, therefore disallowed.


답변

주어진:

public enum PersonType {
    COOL_GUY(1),
    JERK(2);

    private final int typeId;
    private PersonType(int typeId) {
        this.typeId = typeId;
    }

    public final int getTypeId() {
        return typeId;
    }

    public static PersonType findByTypeId(int typeId) {
        for (PersonType type : values()) {
            if (type.typeId == typeId) {
                return type;
            }
        }
        return null;
    }
}

나에게 이것은 일반적으로 데이터베이스의 조회 테이블과 거의 일치하지 않습니다 (드물게 업데이트되는 테이블의 경우에만).

그러나 findByTypeIdswitch 문에서 사용하려고 할 때 (보통 사용자 입력에서) …

int userInput = 3;
PersonType personType = PersonType.findByTypeId(userInput);
switch(personType) {
case COOL_GUY:
    // Do things only a cool guy would do.
    break;
case JERK:
    // Push back. Don't enable him.
    break;
default:
    // I don't know or care what to do with this mess.
}

… 다른 사람들이 말했듯이 이것은 NPE @ switch(personType) {입니다. 구현을 시작한 한 가지 해결 방법 (예 : “솔루션”)은 UNKNOWN(-1)유형 을 추가하는 것이 었습니다 .

public enum PersonType {
    UNKNOWN(-1),
    COOL_GUY(1),
    JERK(2);
    ...
    public static PersonType findByTypeId(int id) {
        ...
        return UNKNOWN;
    }
}

이제는 계산되는 위치에서 널 검사를 수행 할 필요가 없으며 UNKNOWN유형을 처리할지 여부를 선택할 수 있습니다 . (참고 : -1비즈니스 시나리오에서는 가능성이 높지 않지만 사용 사례에 적합한 것을 선택하십시오).


답변

당신은

if (i == null) {
   doSomething0();
} else {
   switch (i) {
   }
}


답변

일부 라이브러리는 내장 Java switch문 에 대한 대안을 제공하려고 합니다. Vavr 은 그중 하나이며 패턴 일치로 일반화합니다.

다음은 해당 문서 의 예입니다 .

String s = Match(i).of(
    Case($(1), "one"),
    Case($(2), "two"),
    Case($(), "?")
);

모든 술어를 사용할 수 있지만 많은 술어를 즉시 제공하며 $(null)완벽하게 합법적입니다. 나는 이것이 대안보다 더 우아한 해결책을 찾았지만, 이것은 java8과 vavr 라이브러리에 대한 의존성이 필요합니다 …