Programming

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

procodes 2020. 6. 7. 17:36
반응형

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;
    }
  }
}

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


This was answered ages ago and probably not relevant, but just in case. When I was confronted with this issue, I simply used an if statement instead of switch, it solved the error. It is of course a workaround and probably not the "right" solution, but in my case it was just enough.


Sometimes the switch variable can also make that error for example:

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

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

   //...
}

To solve you should cast the variable to int(in this case). So:

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

   case 0: //No Error

   //...
}

Got this error in Android while doing something like this:

 roleSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

            switch (parent.getItemAtPosition(position)) {
                case ADMIN_CONSTANT: //Threw the error

            }

despite declaring a constant:

public static final String ADMIN_CONSTANT= "Admin";

I resolved the issue by changing my code to this:

roleSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

            String selectedItem = String.valueOf(parent.getItemAtPosition(position));
            switch (selectedItem) {
                case ADMIN_CONSTANT:

            }

In my case, I was getting this exception because

switch (tipoWebServ) {
                            case VariablesKmDialog.OBTENER_KM:
                                resultObtenerKm(result);
                                break;
                            case var.MODIFICAR_KM:
                                resultModificarKm(result);
                                break;
                        }

in the second case I was calling the constant from the instance var.MODIFICAR_KM: but I should use VariablesKmDialog.OBTENER_KM directly from the class.


If you're using it in a switch case then you need to get the type of the enum even before you plug that value in the switch. For instance :

SomeEnum someEnum = SomeEnum.values()[1];

switch (someEnum) {
            case GRAPES:
            case BANANA: ...

And the enum is like:

public enum SomeEnum {

    GRAPES("Grapes", 0),
    BANANA("Banana", 1),

    private String typeName;
    private int typeId;

    SomeEnum(String typeName, int typeId){
        this.typeName = typeName;
        this.typeId = typeId;
    }
}

I recommend you to use enums :)

Check this out:

public enum Foo 
{
    BAR("bar"),
    BAZ("baz"),
    BAM("bam");

    private final String description;

    private Foo(String description)
    {
        this.description = description;
    }

    public String getDescription()
    {
        return description;
    }
}

Then you can use it like this:

System.out.println(Foo.BAR.getDescription());

참고URL : https://stackoverflow.com/questions/3827393/java-switch-statement-constant-expression-required-but-it-is-constant

반응형