[java] Java 스위치 명령문 : 상수 표현식이 필요하지만 상수입니다.

그래서 나는 몇 가지 정적 상수를 가진이 클래스에서 일하고 있습니다 :

public abstract class Foo {
    ...
    public static final int BAR;
    public static final int BAZ;
    public static final int BAM;
    ...
}

그런 다음 상수를 기반으로 관련 문자열을 얻는 방법을 원합니다.

public static String lookup(int constant) {
    switch (constant) {
        case Foo.BAR: return "bar";
        case Foo.BAZ: return "baz";
        case Foo.BAM: return "bam";
        default: return "unknown";
    }
}

그러나 컴파일 할 때 constant expression required3 개의 사례 레이블 각각에 오류가 발생합니다.

스위치를 컴파일하려면 컴파일러가 컴파일 타임에 식을 알아야한다는 것을 알고 있지만 왜 Foo.BA_상수가 아닌가?



답변

스위치를 컴파일하려면 컴파일러가 컴파일 타임에 식을 알고 있어야하지만 Foo.BA_ 상수가 아닌 이유는 무엇입니까?

필드가 초기화 된 후에 실행되는 코드의 관점에서 보면 일정하지만 JLS에 필요한 의미에서 컴파일 시간 상수 는 아닙니다 . 참조 §15.28 정수 식 (A)의 사양에 대한 상수 식 1 . 이는 다음과 같이 “일정한 변수”를 정의하는 §4.12.4 최종 변수 를 나타냅니다 .

우리는 기본 유형 또는 유형 문자열의 변수를 호출하며, 최종 변수는 컴파일 타임 상수 표현식 (§15.28) 상수 변수로 초기화됩니다. 변수가 상수 변수인지 여부는 클래스 초기화 (§12.4.1), 이진 호환성 (§13.1, §13.4.9) 및 명확한 할당 (§16)과 관련이있을 수 있습니다.

귀하의 예에서 Foo.BA * 변수에는 이니셜 라이저가 없으므로 “일정한 변수”로 규정되지 않습니다. 수정은 간단합니다. 컴파일 타임 상수 표현식 인 이니셜 라이저를 갖도록 Foo.BA * 변수 선언을 변경하십시오.

다른 예제 (이니셜 라이저가 이미 컴파일 타임 상수 표현식 인 경우)에서 final필요한 변수를 선언 합니다.

상수 enum가 아닌 int상수 를 사용하도록 코드를 변경할 수 있지만 다른 몇 가지 제한 사항이 있습니다.


1-상수 표현 제한은 다음과 같이 요약 할 수 있습니다. 일정한 표현) 기본 형식을 사용할 수 있으며, String단, B)의 간격에서 리터럴 (아르 원색 있도록 null할당 연산자 제외 연산자 가능) D, 일정한 표현이 가능 표현식으로 괄호에 있도록)) 및 상수 변수 만, C를 ++, --또는 instanceof, 및 e) 타입 캐스트를 기본 타입으로 String만 허용

참고이 방법 또는 람다 전화의 어떤 형태를 포함하지 않는 것을 new, .class. .length또는 배열 첨자. 또한 배열 값, enum값, 프리미티브 래퍼 유형의 값, 복싱 및 언 박싱의 사용은 모두 a) 때문에 제외됩니다.


답변

당신은 얻을 상수 표현이 필요 당신이 당신의 상수 떨어져 값을 왼쪽 때문이다. 시험:

public abstract class Foo {
    ...
    public static final int BAR=0;
    public static final int BAZ=1;
    public static final int BAM=2;
    ...
}


답변

Android 에서이 오류가 발생했으며 솔루션은 다음과 같습니다.

public static final int TAKE_PICTURE = 1;

대신에

public static int TAKE_PICTURE = 1;


답변

컴파일 시간 상수가 아니기 때문입니다. 다음과 같은 유효한 코드를 고려하십시오.

public static final int BAR = new Random().nextInt();

BAR런타임 의 값만 알 수 있습니다 .


답변

이 예제와 같이 열거 형을 사용할 수 있습니다.

public class MainClass {
enum Choice { Choice1, Choice2, Choice3 }
public static void main(String[] args) {
Choice ch = Choice.Choice1;

switch(ch) {
  case Choice1:
    System.out.println("Choice1 selected");
    break;
 case Choice2:
   System.out.println("Choice2 selected");
   break;
 case Choice3:
   System.out.println("Choice3 selected");
   break;
    }
  }
}

출처 :
열거 형이있는 스위치 문


답변

이것은 오래 전에 대답되었지만 아마도 관련이 없지만 경우에 따라 가능합니다. 이 문제에 직면했을 때 간단히 if대신 문을 사용 switch하여 오류를 해결했습니다. 물론 해결 방법이며 아마도 “올바른”해결책은 아니지만 제 경우에는 충분했습니다.


답변

때때로 스위치 변수 가 다음과 같은 오류를 일으킬 수도 있습니다.

switch(view.getTag()) {//which is an Object type

   case 0://will give compiler error that says Constant expression required

   //...
}

해결하려면 변수를 int로 캐스팅해야합니다 (이 경우). 그래서:

switch((int)view.getTag()) {//will be int

   case 0: //No Error

   //...
}