7

Trình biên dịch Java xử lý khối chuyển đổi sau đây như thế nào? Phạm vi của biến 'b' là gì?Chuyển đổi Java: khai báo biến và phạm vi

Lưu ý rằng biến 'b' chỉ được khai báo trong nhánh đầu tiên của câu lệnh switch. Cố gắng khai báo nó trong nhánh thứ hai cũng dẫn đến lỗi biên dịch "biến cục bộ trùng lặp".

int a = 3; 
    switch(a) { 
    case 0: 
     int b = 1; 
     System.out.println("case 0: b = " + b); 
     break; 
    case 1: 
     // the following line does not compile: b may not have been initialized 
     // System.out.println("case 1 before: b = " + b); 
     b = 2; 
     System.out.println("case 1 after: b = " + b); 
     break; 
    default: 
     b = 7; 
     System.out.println("default: b = " + b); 
    } 

Lưu ý: mã trên biên dịch với trình biên dịch java 1.6.

+0

Đã trả lời câu hỏi của riêng bạn. – darrengorman

Trả lời

21

Phạm vi này, giống như thường lệ, được giới hạn bởi {}.

+7

Tin nhắn cho OP, bạn có thể đặt niềng răng xung quanh mỗi trường hợp và sau đó nó sẽ làm việc. Như trong trường hợp 1: {doHere(); phá vỡ; } ' – jn1kk

10

Phạm vi của b là khối. Bạn chỉ có một khối bao gồm tất cả case s. Đó là lý do tại sao bạn gặp lỗi biên dịch khi bạn redeclare b trong số case thứ hai của bạn.

Bạn có thể quấn mỗi case trong một khối riêng như

case 0: 
    { 
    int b = 1; 
    ... 
    } 
case 1: 
    { 
    int b = 2; 
    ... 
    } 

nhưng tôi nghĩ FindBugs hoặc CheckStyle sẽ phàn nàn về điều đó.

+4

Lỗi biên dịch không phải từ _redeclaring_' b' nhưng từ truy cập nó trước khi nó được khởi tạo. 'b' là hoàn toàn hợp lệ trong trường hợp 0, 1 và mặc định bởi vì khi bạn đề cập đến nó nằm trong phạm vi.Vấn đề với dòng nhận xét của ông không biên dịch là b không được khởi tạo trước khi nó được truy cập. – NominSim

+0

Tôi nên đọc câu hỏi cẩn thận hơn. Tôi nghĩ anh ta đang làm 'int b = 2' trong dòng chú thích ;-) – Kai

0

Các khối case của bạn không có bất kỳ phạm vi địa phương nào. Nó không phải là một loạt các if ... else if ... else khối, java thực hiện nó dưới dạng một loạt các GOTO s.

3

Phạm vi b là khối switch - giữa việc kê khai và delimiter } -

int a = 3; 

switch(a) { 
    case 0: 
      int b = 1; //scope starts 
      System.out.println("case 0: b = " + b); 
      break; 
    case 1: 
      // the following line does not compile: b may not have been initialized 
      // System.out.println("case 1 before: b = " + b); 
      b = 2; 
      System.out.println("case 1 after: b = " + b); 
      break; 
    default: 
      b = 7; 
      System.out.println("default: b = " + b); 
}//scope ends 

Tuy nhiên, bạn cần phải biết rằng nếu bạn khai báo int b bên trong case 1:, bạn sẽ KHÔNG có quyền truy cập vào biến b bên trong case 0:

Để trả lời câu hỏi bạn hỏi trong java bình luận của bạn có thể kiểm tra ví dụ này đơn giản hơn:

int b; 
if(true){ 
    b++; //The local variable b hast not been initialized 
} 

Hy vọng điều đó sẽ hữu ích.

1

trong mã của bạn nếu số không bằng 0 b sẽ không bao giờ được khởi tạo. bạn nên định nghĩa b trước câu lệnh switch.

+0

Vấn đề là lúc biên dịch, không phải lúc chạy. –

0

Phạm vi biến được xác định trong câu lệnh switch() sẽ giống như trong một khối bình thường được bao quanh bởi {}.

Do đó, mọi biến được xác định trong câu lệnh switch() hiển thị cho toàn bộ khối, sau khi được xác định.

3

Bạn có thể xác định phạm vi sử dụng {} xung quanh trường hợp của bạn.

int a = 3; 
switch(a) { 
case 0: { 
    int b = 1; 
    System.out.println("case 0: b = " + b); 
    break; 
} 
case 1: { 
    // the following line does not compile: b may not have been initialized 
    // System.out.println("case 1 before: b = " + b); 
    int b = 2; 
    System.out.println("case 1 after: b = " + b); 
    break; 
} 
default: { 
    int b = 7; 
    System.out.println("default: b = " + b); 
} 
} 
Các vấn đề liên quan