2015-02-12 18 views
7

Đây là mã Java:IntelliJ IDEA Hợp đồng Báo cáo vi phạm Cảnh báo

public static boolean anyEqual(Object needle, Object... haystack) { 
    if(needle == null || haystack == null) { 
     return false; 
    } 
    if(haystack.length == 0) { 
     return false; 
    } 
    for(Object match : haystack) { 
     if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) { 
      return true; // warning from IntelliJ here, 'contract clause !null, null -> false is violated' 
     } 
    } 
    return false; 
} 

Có ai có bất kỳ ý tưởng tại sao điều này đang được hiển thị? contract clause !null, null -> false is violated? Cảm ơn!

IntelliJ 14.0.2 build: 139,659

Ảnh chụp màn hình: enter image description here

+0

Có bất kỳ chú thích trên phương pháp này? – vikingsteve

+0

@vikingsteve no – jn1kk

+1

Có vẻ như https://youtrack.jetbrains.com/issue/IDEA-136079, được sửa trong 14.1 EAP tại https://confluence.jetbrains.com/display/IDEADEV/IDEA+14.1+EAP –

Trả lời

5

IntelliJ được phỏng đoán chính thức contract của phương pháp của bạn sẽ được này:

null, _ -> false; !null, null -> false 

Điều này thực sự có nghĩa là:

  • Các quy định cụ thể hợp đồng đầu tiên rằng, miễn là tham số đầu tiên là null, nó sẽ trả về false. Này được quan sát bởi tuyên bố if đầu tiên của bạn:

    if(needle == null || haystack == null) { 
        return false; 
    } 
    
  • Hợp đồng thứ hai xác định rằng, nếu tham số thứ hai là null, sau đó nó sẽ trở lại false. Điều này cũng được chỉ định bởi cùng một tuyên bố if ở trên.

Đường ruột của tôi cho tôi biết rằng IntelliJ đang gặp khó khăn trong việc hiểu rõ hợp đồng chính thức của vòng lặp là gì, mặc dù nó đơn giản như một điều kiện khác trong biểu thức hợp đồng.

for(Object match : haystack) { 
    if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) { 
     return true; 
    } 
} 

Hãy xem qua một thời gian ngắn.

  • Báo cáo nâng cao sẽ không kích hoạt nếu haystack có độ dài 0, do đó, đó là điều cần cân nhắc.
  • Các phần tử bên trong mảng có thể là null và tôi không hoàn toàn chắc chắn rằng phân tích tĩnh của IntelliJ bao gồm phần đó chưa.
  • Chúng tôi đã thiết lập rằng needle phải không có giá trị, vì vậy không có gì vi phạm hợp đồng tại dòng đó.
  • Nếu chúng tôi có kịch bản trong đó match != null && needle.getClass() == match.getClass() && needle.equals(match)true, chúng tôi trả lại true. Nếu không, chúng tôi trả lại false.

nothing that I can see in the formal documentation cung cấp cho chúng tôi cụm từ mà chúng tôi yêu cầu, "hey - chúng tôi đang kiểm tra các thành phần của một mảng!"; có thể là trường hợp phân tích đang vấp ngã trên thực tế là chúng tôi đang trả lại true bất chấp những gì chúng tôi đã nêu ở trên (kể từ haystack là không null).

Cho phép tôi nhấn mạnh điểm này:

haystack phải là phi null để các bạn tham gia vào các cải tiến-cho. Mã của bạn sẽ không hoạt động nếu không.

Tất cả trong tất cả, tôi sẽ không lo lắng về điều đó. Tốt hơn, hãy nộp một lỗi chống lại nó để loại điều này có thể được cố định hoặc mở rộng theo.

+0

Liên kết tới tài liệu chú thích Hợp đồng IntelliJ bị hỏng. [Phiên bản hiện tại tại đây] (https://www.jetbrains.com/idea/help/contract-annotations.html). – Flavin

+0

@Flavin: Cảm ơn, nhưng trong tương lai bạn có thể đề xuất chỉnh sửa. Tôi đã có khả năng chấp thuận điều đó. – Makoto

-3

nhắn này đã được chứng minh bởi vì kiểm tra IntelliJ vi phạm hợp đồng phương pháp. Đó là một tính năng tương đối mới, đọc thêm tại https://www.jetbrains.com/idea/features/annotation_java.html

+0

Vì vậy, có , chúng ta có thể hiểu đó là một tính năng. Những gì chúng tôi muốn hiểu là * tại sao * nó hoạt động theo cách này. – Makoto

1

Điều này trông giống như lỗi IntelliJ đối với tôi, vì bằng cách xóa từ khóa static khỏi phương thức mà cảnh báo biến mất.

Điều gì đó phải gây nhầm lẫn với phân tích tĩnh tại đây. Người ta luôn có thể gửi nó cho bạn để các nhà phát triển máy bay phản lực có thể nhìn vào nó.

Có người đã báo cáo vấn đề này Here

(thử nghiệm trên v14.0.3)

+0

Hoặc thay đổi kiểu trả về Boolean và trả về Boolean.TRUE, nó cũng sẽ biến mất. – chenrui

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