web-dev-qa-db-ja.com

Switch Java problem:case式は定数式でなければならない

Switch/caseステートメントに問題があります。エラーには、「ケース式は定数式でなければなりません」とあります。私はエラーを理解しており、Ifを使用して解決できますが、誰かがケース式がスイッチ/ケースで一定でなければならない理由を教えてもらえますか?私のエラーのコード例:

public boolean onOptionsItemSelected(MenuItem item) {
    int idDirectory = ((MenuItem) findViewById(R.id.createDirectory)).getItemId();
    int idSuppression = ((MenuItem) findViewById(R.id.recycleTrash)).getItemId();
    int idSeeTrash = ((MenuItem) findViewById(R.id.seeTrash)).getItemId();

    switch (item.getItemId()) {
    case idDirectory:
        createDirectory(currentDirectory);
        break;
    case idSuppression:
        recycleTrash();
        break;
    case idSeeTrash:
        seeTrash();
        break;
    }

    return super.onOptionsItemSelected(item);
}

あなたの説明のためのTHX !!

26
Dimitri

そのため、コンパイル段階で評価できます(静的にチェックします)

switchの正式な定義については、 http://docs.Oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11 を参照してください。 。

さらに、switchがバイトコードに変換される方法をよりよく理解するのに役立つ場合があります。

class Switch {
  void x(int n ) {
    switch( n ) {
      case 1: System.out.println("one"); break;
      case 9: System.out.println("nine"); break;
      default:  System.out.println("nothing"); break;
    }
  }
}

そしてコンパイル後:

C:\>javap -c Switch
Compiled from "Switch.Java"
class Switch extends Java.lang.Object{
Switch();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method Java/lang/Object."<init>":()V
   4:   return

void x(int);
  Code:
   0:   iload_1
   1:   lookupswitch{ //2
                1: 28;
                9: 39;
                default: 50 }
   28:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   31:  ldc     #3; //String one
   33:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   36:  goto    58
   39:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   42:  ldc     #5; //String nine
   44:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   47:  goto    58
   50:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   53:  ldc     #6; //String nothing
   55:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   58:  return

}

1:としてマークされた行を参照してください

 1:   lookupswitch{ //2
            1: 28;
            9: 39;
            default: 50 }

値を評価し、他の行に進みます。たとえば、値が9の場合、命令39にジャンプします。

   39:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   42:  ldc     #5; //String nine
   44:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   47:  goto    58

次に命令58にジャンプします。

   58:  return

動的に評価された場合、これはすべて不可能です。それが理由です。

54
OscarRyz

eclipseでIDEはシンプル、スイッチ文CTRL + 1でスイッチ文を変換-if-else文 http://tools.Android.com/tips/non-constant-フィールド

13
ingyesid

idDirectoryなどは、宣言された変数ではなく、定数である必要があります。この場合、Switchは機能しません。if-elseコンストラクトに切り替える必要があります。

[〜#〜] edit [〜#〜] OPの意味がわかりました。これは、Java言語。

3
fastcodejava