그래서 나는 몇 가지 정적 상수를 가진이 클래스에서 일하고 있습니다 :
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 required
3 개의 사례 레이블 각각에 오류가 발생합니다.
스위치를 컴파일하려면 컴파일러가 컴파일 타임에 식을 알아야한다는 것을 알고 있지만 왜 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
상수 를 사용하도록 코드를 변경할 수 있지만 다른 몇 가지 제한 사항이 있습니다.
- 당신은 해야한다 포함
default
당신이 경우에도, 케이스case
의 모든 알려진 값enum
; 열거 형의 스위치에 기본값이 필요한 이유를 참조하십시오 . case
라벨은 모두 명시해야합니다enum
값,하지로 평가 표현enum
값.
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
//...
}