2010-01-09 29 views
9

Tôi là một fan hâm mộ lớn của tự động đấm bốc trong Java vì nó tiết kiệm rất nhiều mã tấm nồi hơi xấu xí. Tuy nhiên tôi đã tìm thấy tự động unboxing được gây nhầm lẫn trong một số trường hợp đối tượng Number có thể là null. Có cách nào để phát hiện nơi tự động unboxing đang xảy ra trong một codebase với một cảnh báo javac? Bất kỳ giải pháp nào khác để phát hiện sự xuất hiện của unboxing chỉ (chẳng hạn như FindBugs hoặc cảnh báo trình biên dịch cụ thể của Eclipse) sẽ được đánh giá cao vì tôi không thể tìm thấy bất kỳ.Java tự động unboxing - là có một cảnh báo trình biên dịch?

Để làm rõ tôi không muốn bất kỳ cảnh báo nào được tạo trên boxing - chỉ unboxing.

Đây là một ví dụ đơn giản của một số mã có thể gây nhầm lẫn NullPointerExceptions:

class Test { 
    private Integer value; 

    public int getValue() { 
     return value; 
    } 
} 

Trả lời

1

Eclipse sẽ cho phép bạn thực hiện các hoạt động đấm bốc và giải mã màu cú pháp (nhưng không phải là thao tác này hay cách khác). Tôi đã đặt chúng thành màu đỏ tươi: nếu xảy ra, điều đó có nghĩa là tôi đã cẩu thả trong việc khớp các tham số và đối số.

+0

Cảm ơn - Tôi nghĩ tôi sẽ làm như vậy. Ngay cả khi nó không nắm bắt được vấn đề nó sẽ làm cho gỡ lỗi vấn đề dễ dàng hơn. –

+2

Có sự cố khi tách quyền anh khỏi cảnh báo unboxing: https://bugs.eclipse.org/bugs/show_bug.cgi?id=163065 – Kyle

5

Yup. Trong Eclipse:

Preferences-> Java-> Compiler-> Lỗi/Warnings-> Lập trình tiềm năng Problems-> Boxing và chuyển đổi unboxing

+0

Rất tiếc, tôi có thể rõ ràng hơn (tôi sẽ sửa đổi câu hỏi). Tôi muốn một cảnh báo về unboxing nhưng không phải trên boxing. –

+0

Ah, không Eclipse nào sẽ không cho phép bạn phân biệt giữa hai. – skaffman

+0

@skaffman Hy vọng điều này: https://bugs.eclipse.org/bugs/show_bug.cgi?id=163065 sẽ được triển khai. – Kyle

2

Đáng tiếc là không có. Đây là một trong những vấn đề với số tự động mở hộp. Bạn có thể

  • Khởi tạo nó thành một giá trị mặc định, chẳng hạn như private Integer value = 0
  • Kiểm tra cho một null return value != null ? value : 0

Cá nhân tôi thích phương pháp đầu tiên. Nói chung tôi sẽ nghĩ rằng bạn sẽ không có quá nhiều trường hợp, nơi bạn cần phải có một số null.

Ngoài ra, tại sao bạn sử dụng Số nguyên lớn để lưu trữ giá trị. Nếu bạn chỉ trở lại một chút int, tại sao không lưu trữ nó theo cách đó?

+0

Đôi khi khả năng hoạt động của API/giao diện yêu cầu trả về int trong khi Long/BigInteger sẽ khả dụng. Oh làm thế nào tôi muốn có một 'Danh sách' với mục' Long.MAX_VALUE' nhưng tôi không thể làm điều đó. – Esko

+0

Bạn có thể có một 'Danh sách' lớn; nó không thể nói với bạn rằng nó to lớn. Trong 'LinkedList', ví dụ, nó duy trì một trường' size' của kiểu 'int', nhưng nó không bao giờ kiểm tra để đảm bảo rằng kích thước không tràn. Tuy nhiên, có một số hoạt động sẽ không thành công dựa trên việc đảm bảo rằng chỉ mục hiện tại * nhỏ hơn * kích thước, sẽ không giữ được nếu trường 'size' tràn vào giá trị âm. – seh

+0

Tôi không thể sử dụng 'Danh sách' với các mục Long.MAX_VALUE như là một thay thế thả vào trong mã của tôi và đó là điều quan trọng. Tôi biết rất rõ ngữ nghĩa của 'AbstractList' và những thứ tương tự, tuy nhiên miễn là giao diện tự nó nói' int', tôi bị ràng buộc với nó. – Esko

1

Tôi nghi ngờ rằng đây sẽ là trường hợp cảnh báo. Đây là một trong những quirks của auto-boxing.

Joshua Bloch giải quyết vấn đề này trong cuốn sách "Java hiệu quả" của mình. Về cơ bản, trình biên dịch đang cố gắng làm nhiều hơn cho bạn những gì được mong đợi. Nói cách khác, loại vấn đề này thường có liên quan đến việc sử dụng và kết quả là, rất khó để "phát hiện lỗi" khi lỗi là, ngữ nghĩa nói, đơn giản là không có.

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