2011-01-20 3 views
26

Tôi gặp sự cố trong báo cáo chuyển đổi/trường hợp của mình. Lỗi nói: "Biểu thức trường hợp phải là biểu thức hằng số". Tôi hiểu lỗi và tôi có thể giải quyết nó bằng cách sử dụng Nếu ai đó có thể cho tôi biết lý do tại sao biểu thức trường hợp phải không đổi trong một chuyển đổi/trường hợp. Ví dụ về lỗi của tôi:Sự cố chuyển đổi Java: biểu thức trường hợp phải là biểu thức không đổi

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 giải thích của bạn !!

+5

Tại sao các bạn sử dụng 'findViewById() getItemId()'.? Nếu bạn đã có id, bạn không cần lấy item để lấy id! –

+2

báo cáo chuyển đổi là mùi hôi ... Tôi khuyên bạn nên xem xét sử dụng đa hình hoặc mẫu bộ điều hợp để đạt được mã tìm kiếm tốt hơn. Ngoài ra, bạn có thể tránh các vấn đề như thế này hoàn toàn. – Bnjmn

+0

@Bnjmn Tôi đồng ý, đặc biệt khi điều kiện lặp lại khá thường xuyên. Nếu bạn sử dụng nó hiếm khi nó có thể được ok. Ngoài ra, tôi sử dụng nó đôi khi với đa hình để tạo ra ví dụ cụ thể ban đầu. – OscarRyz

Trả lời

54

Vì vậy, nó có thể được đánh giá trong giai đoạn biên soạn (tĩnh kiểm tra)

Xem: http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11 cho một định nghĩa chính thức của switch.

Bên cạnh đó nó có thể giúp bạn hiểu rõ hơn về cách mà switch được chuyển thành bytecode:

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

Và sau khi biên dịch:

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 

} 

Xem dòng đánh dấu là 1:

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

Nó đánh giá giá trị và đi đến som e dòng khác. Ví dụ nếu giá trị là 9 nó sẽ nhảy đến hướng dẫn 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 

Mà lần lượt nhảy để hướng dẫn 58:

58: return 

Tất cả điều này sẽ không thực hiện được nếu nó được đánh giá năng động. Đó là lý do tại sao.

+0

Cảm ơn người đàn ông, đó là một câu trả lời hay.Vì vậy, nếu biên dịch với javap, tôi có thể thấy bytecode tạo ra ?? – Dimitri

+1

@Dimitri. Không có gì. 'javap' là một công cụ khác (như javadoc hoặc jar), là trình phân tích cú pháp java mặc định. Nếu được gọi với '-c', bạn sẽ thấy các hướng dẫn này. – OscarRyz

+0

Ok. Nhưng tôi đã suy nghĩ, bạn có nghĩ rằng bytecode tạo ra trong JVM là như nhau trong Dalvik Machine (Android). Tôi đang làm việc trên Android như bạn có thể thấy nó – Dimitri

3

idDirectory và các loại khác cần phải là biến cố định và không được khai báo. Switch sẽ không hoạt động trong trường hợp này, bạn cần chuyển sang cấu trúc if-else.

EDIT Tôi hiểu ý nghĩa của OP. Đó chỉ là cách chuyển đổi hoạt động trong ngôn ngữ java.

+0

Đây chính là vấn đề của bạn. Nếu bạn không thể giải quyết vấn đề này với các hằng số, hãy sử dụng thiết lập if-then-else-if-blah-blah phức tạp hơn một chút. –

+7

-1 Để trả lời những gì OP đã biết: * Tôi hiểu lỗi và tôi có thể giải quyết bằng cách sử dụng Nếu ai đó có thể cho tôi biết lý do biểu thức trường hợp phải liên tục trong một chuyển đổi/trường hợp * – OscarRyz