2011-12-19 33 views
18

Tôi có một số câu lệnh chuyển đổi như hình dưới đây. Chú ý không có nghỉ. Findbugs chỉ báo cáo lỗi trên báo cáo trường hợp thứ hai. Lỗi là: Lệnh chuyển đổi được tìm thấy trong đó một trường hợp rơi vào trường hợp tiếp theo.Chuyển đổi mà không cần ngắt

switch(x) { 

    case 0: 
     // code 

    case 1: 
     // code 

    case 2: 
     // code 
} 
+3

thông báo lỗi nói gì? –

+9

Và vấn đề là ...? – fge

+0

Bạn có chắc chắn đó không phải là cảnh báo thay vì lỗi không? – xagyg

Trả lời

2

Nếu không có giờ nghỉ họ sẽ rơi dù vào nhau vì vậy nếu x == 0 bạn sẽ đi qua tất cả các mã trong mỗi khối báo cáo trường hợp. Findbugs có thể là sai về lỗi, hoặc nó có thể là một điều kiện lỗi mà không có sự phá vỡ, tức là một cái gì đó trong case 0 gây ra một cái gì đó trong case 1 để phá vỡ.

Nếu không có mã và lỗi chính xác, tôi thực sự không thể trợ giúp thêm. Việc thiếu nghỉ có cố ý không?

60

Findbugs đang gắn cờ mà rơi từ một case sang tiếp theo thường không phải là ý tưởng hay nếu có bất kỳ mã nào trong mã đầu tiên (mặc dù đôi khi nó có thể được sử dụng để có hiệu quả tốt). Vì vậy, khi nó thấy số case thứ hai và không có break, báo cáo sẽ báo lỗi.

Vì vậy, ví dụ:

switch (foo) { 
    case 0: 
     doSomething(); 
    case 1: 
     doSomethingElse(); 
    default: 
     doSomeOtherThing(); 
} 

này là hoàn toàn hợp lệ Java, nhưng nó có lẽ không làm những gì tác giả dự định: Nếu foo0, cả ba các chức năng doSomething, doSomethingElse, và doSomeOtherThing chạy (theo thứ tự đó). Nếu foo1, chỉ doSomethingElsedoSomeOtherThing chạy. Nếu foo là bất kỳ giá trị nào khác, chỉ doSomeOtherThing chạy.

Ngược lại:

switch (foo) { 
    case 0: 
     doSomething(); 
     break; 
    case 1: 
     doSomethingElse(); 
     break; 
    default: 
     doSomeOtherThing(); 
     break; 
} 

Ở đây, chỉ có một số chức năng sẽ chạy, tùy thuộc vào giá trị của foo.

Vì đây là lỗi mã hóa phổ biến để quên break, các công cụ như Findbugs gắn cờ cho bạn.

Có một use-case thông thường, nơi bạn có nhiều case báo cáo trong một hàng với không can thiệp mã:

switch (foo) { 
    case 0: 
    case 1: 
     doSomething(); 
     break; 
    case 2: 
     doSomethingElse(); 
     break; 
    default: 
     doSomeOtherThing(); 
     break; 
} 

Ở đó, chúng tôi muốn gọi doSomething nếu foo0hay1. Hầu hết các công cụ sẽ không gắn cờ điều này như là một lỗi mã hóa có thể xảy ra, bởi vì không có mã nào trong số case 0 trước case 1 và đây là một mẫu khá phổ biến.

+1

Có phải 'break' thực sự cần thiết ở cuối? – kcpr

+2

@kcpr: Nói đúng ra, bạn không cần một 'ngắt;' trên trường hợp cuối cùng của một công tắc ('mặc định' ở trên). Nhưng tôi thích sự nhất quán. Nó hoàn toàn là một vấn đề về phong cách, cùng một bytecode được sản xuất theo một trong hai cách. (Đây không phải là, tất nhiên, đúng nếu bạn rời khỏi bất kỳ * khác * 'phá vỡ;'.) –

+0

Đây là một mô tả rất tốt về vấn đề chung và cách chuyển đổi hoạt động, nhưng không thực sự trả lời câu hỏi của OP - mặc dù, nói đúng, OP không thực sự trình bày một câu hỏi ... – Tasgall

3

Chuyển đổi thông tin thu gọn thuộc danh mục Findbugs của "mã độc quyền". Tôi nghĩ rằng nó chỉ cờ đầu tiên xuất hiện của một mùa thu thông qua trong một tuyên bố chuyển đổi để cắt giảm số lượng các thông báo lỗi.

4

Tôi đã viết những nhận xét này nhưng không hiển thị. Tôi đang biến chúng thành một câu trả lời. Đây thực sự là một phần mở rộng cho T.J.Crowder's answer.

Bạn có thể tìm thấy quy tắc có liên quan khiến Findbugs báo cáo lỗi here.

Bạn có thể ngăn chặn Findbugs báo cáo loại lỗi này bằng cách tạo tệp xml có nội dung sau, nói filter.xml và chạy công cụ với tùy chọn -exclude filter.xml. Xem filters on Findbugs.

<FindBugsFilter> 
    <Match> 
    <Bug category="PERFORMANCE" /> 
    </Match> 
</FindBugsFilter> 
+0

Trên Stack Overflow, nó thực sự hoàn toàn chấp nhận được để chỉnh sửa câu trả lời của người khác để thêm thông tin hữu ích (chẳng hạn như ở trên). Đi cho nó! –

+1

@ T.J.Crowder tiếc là các chỉnh sửa của tôi đã bị từ chối, tôi đã phải hủy xóa câu trả lời của mình. Cảm ơn bạn đã đề xuất. – melihcelik

+0

Tôi nghi ngờ quy tắc thực sự là tổng quát hơn ['SF_SWITCH_FALLTHROUGH'] (http: // findbugs.sourceforge.net/bugDescriptions.html#SF_SWITCH_FALLTHROUGH). 'SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH' có nghĩa là," không chỉ có một sự sụp đổ, mà còn có một thứ gì đó mà bạn đã cố gắng lưu trong một trường hợp trước ". Đó là nhiều khả năng là một lỗi, theo ý kiến ​​của tôi, vì vậy tôi sẽ được nhiều hơn nữa do dự để vô hiệu hóa các quy tắc 'DEAD_STORE' hơn so với quy tắc' FALLTHROUGH'. –

2

Công cụ phân tích lỗi thường không thích mã giảm vì trong hầu hết các trường hợp, người dùng đã quên viết ghi.

Tôi không biết nếu có một cách cụ thể vô hiệu hóa các cảnh báo với FindBugs nhưng Checkstyle công cụ nhận bình luận đặc biệt như /* fallthrough */ để giả định rằng người dùng thực sự muốn đoạn mã sau để được thực thi. Đặt loại nhận xét này cũng cải thiện khả năng đọc. http://checkstyle.sourceforge.net/config_coding.html#FallThrough

Quy ước mã Java cũng đề cập đến việc sử dụng nhận xét giảm. http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-142311.html

0

Nếu trường hợp của bạn không bị gián đoạn, khi trường hợp là công tắc kích hoạt sẽ đi qua tất cả các trường hợp cho đến khi phát hiện ngắt hoặc kết thúc các trường hợp. Nếu bạn có trường hợp mặc định, nó sẽ kích hoạt nếu giá trị chuyển đổi của bạn trong trường hợp này foo không khớp với bất kỳ trường hợp nào khác.

Các vấn đề liên quan