Câu hỏi Có cần kiểm tra null trước khi gọi instanceof không?


Sẽ null instanceof SomeClass trở về false hoặc ném một NullPointerException?


1088
2018-06-01 13:53


gốc


Nó cũng 'quan trọng' hoặc ít nhất là rất hữu dụng như là một dòng 'bắt đầu thực hành tốt nhất' (hoặc rất sớm) cho bất kỳ So sánh hoặc Bằng hoặc phương pháp tương tự nào được thiết kế để chỉ thành công trên các đối tượng không null cùng loại và bảo vệ bạn chống lại 'trường hợp ngớ ngẩn' trong một dòng. ít mã hơn = ít lỗi hơn.
Để cân nhắc "điều này có hữu ích không?" tranh luận - Tôi chưa bao giờ viết mã Java của riêng mình (vì vậy không dễ dàng biết được thông số kỹ thuật ở đâu và biên dịch một bài kiểm tra sẽ rất nhỏ), nhưng hiện tại tôi đang chuyển đổi thủ công Java sang JavaScript. Mã của tôi đã thất bại trên một tham chiếu null, và googling này cho tôi thấy câu trả lời được chấp nhận, trong đó xác nhận rằng nó đã được mong đợi hành vi và rằng tôi đã mất một kiểm tra null ngầm. Rất hữu ích, trong trường hợp của tôi. - Scott Mermelstein
Câu trả lời ở đây tiết kiệm thời gian. Đọc tất cả các bình luận ... - Adrian
> Một người khôn ngoan có thể học nhiều hơn từ một câu hỏi ngu xuẩn hơn là một kẻ ngốc có thể học hỏi từ một câu trả lời khôn ngoan. - phi
idownvotedbecau.se/noattempt - Robert Columbia


Các câu trả lời:


Không, không cần kiểm tra null trước khi sử dụng instanceof.

Cách diễn đạt x instanceof SomeClass Là false nếu x Là null.

Từ Đặc tả Ngôn ngữ Java, phần 15.2.2, "Loại so sánh toán tử instanceof":

"Vào thời gian chạy, kết quả của    instanceof toán tử là true nếu   giá trị của RelationalExpression  Là   không phải null và tham chiếu có thể là   đúc vào Loại tham chiếu   mà không nuôi một ClassCastException.   Nếu không thì kết quả là false. "

Vì vậy, nếu toán hạng là null, kết quả là sai.


1456
2018-06-01 14:05



Câu trả lời này chính xác hơn try it bởi vì hành vi hiện tại không giống như hành vi được bảo đảm. - Luke
Câu hỏi này xuất hiện trong chương Joshua Bloch về bình đẳng đối tượng trong Effective Java - - amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683 - Kevin Meredith
Cụ thể, trong mục 8, ông lưu ý rằng trong phương thức equals (), một toán tử instanceof phục vụ hai mục đích - nó xác minh rằng đối số là cả hai không null và kiểu đúng. "... [S] o bạn không cần một kiểm tra null riêng biệt." - Andy Thomas
@BenThurley - Java instanceof nhà điều hành là một phần của Java 1.0, được phát hành gần 20 năm trước. Thay đổi hành vi ngay bây giờ theo cách mà có thể phá vỡ mã hiện tại là không, không có một số lợi ích mà lớn hơn chi phí khổng lồ đó. Hai mươi năm trước, có lẽ đã có thể có lý lẽ cho việc trả lại iff thật sự đối số có thể được đúc, hoặc ném một ngoại lệ cho một đối số null. Nhưng những định nghĩa đó sẽ yêu cầu kiểm tra null riêng biệt. - Andy Thomas
@BenThurley - Hành vi được đảm bảo bởi các đặc tả Java trong quá khứ và hiện tại. Tôi nghĩ điểm của Lu-ca giải quyết những hạn chế của việc thử nghiệm trong việc xác định hành vi được bảo đảm của hiện tại. - Andy Thomas


Sử dụng tham chiếu null làm toán hạng đầu tiên instanceof trả về false.


237
2018-06-01 13:53



(Và bây giờ phải mất 10 giây để tìm câu hỏi này trong Google) - PL_kolek
@PL_kolek: Tôi thứ hai. Tại sao bị phân tâm từ nhiệm vụ trong tầm tay, nếu bạn có thể nhanh chóng xác minh với Google? Ví dụ, tôi đang ở giữa một quá trình tái cấu trúc lớn, và tôi không muốn thiết lập một thử nghiệm ở bên cạnh. - paulkore
Quá ngắn. Một câu trả lời tốt cung cấp ngữ cảnh và giải thích. - david.pfx


Câu hỏi rất hay. Tôi chỉ cố gắng cho bản thân mình.

public class IsInstanceOfTest {

    public static void main(final String[] args) {

        String s;

        s = "";

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));

        s = null;

        System.out.println((s instanceof String));
        System.out.println(String.class.isInstance(s));
    }
}

Bản in

true
true
false
false

JLS / 15.20.2. Loại đối sánh toán tử so sánh

Vào thời gian chạy, kết quả của instanceof toán tử là true nếu giá trị của RelationalExpression không phải là null và tham chiếu có thể được truyền đến Loại tham chiếu mà không nuôi một ClassCastException. Nếu không thì kết quả là false.

API / Class # isInstance (Đối tượng)

Nếu điều này Class đối tượng đại diện cho một giao diện, phương thức này trả về true nếu lớp hoặc bất kỳ lớp cha nào được chỉ định Object đối số thực hiện giao diện này; nó trở lại false nếu không thì. Nếu điều này Class đối tượng đại diện cho một kiểu nguyên thủy, phương thức này trả về false.


61
2017-07-29 11:55



Loại khó hiểu. s là một String bởi vì nó nói "String s", s không phải là một String bởi vì nó là null. Vậy địa ngục là gì? - Kai Wang
@KaiWang s chỉ là một biến tham chiếu đối tượng. Nó có thể là một đối tượng thực sự tồn tại ("") hoặc nó có thể ám chỉ một () null tham chiếu theo nghĩa đen. - Jin Kwon
Tôi vẫn còn bối rối. s có thể là null bây giờ, nhưng nó chỉ có thể được trỏ đến một thể hiện String sau đó. Nó không thể được chỉ ra, giống như, một Integer. Vì vậy, nó vẫn là loại của một String, thậm chí nó là một null. Chỉ cần không có ý nghĩa nhiều ... - Kai Wang
@KaiWang Bạn đang nhầm lẫn với loại biến với loại đối tượng thực tế. Các biến không phải là các cá thể; chúng chỉ là con trỏ. null không phải là chuỗi dữ liệu, bất kể biến nào trỏ đến nó. s instanceof String không giống như field.getType().equals(String.class), ví dụ. - Matthew Read
@KaiWang bạn phải tưởng tượng rằng trong cuộc gọi s instanceof String các s được thay thế bằng giá trị thực, do đó sẽ trở thành "" instanceof String và null instanceof String. Suy nghĩ về nó như thế này có thể có ý nghĩa hơn. - Timo Türschmann


Không, không phải. instanceof sẽ trở lại false nếu toán hạng đầu tiên của nó là null.


23
2018-06-01 13:53





Không. Chữ viết Java null không phải là một thể hiện của bất kỳ lớp nào. Do đó nó không thể là một instanceof bất kỳ lớp nào. instanceof  sẽ trả về false hoặc là true do đó <referenceVariable> instanceof <SomeClass> trả về false khi nào referenceVariable giá trị là null.


5
2018-05-27 10:59



Đó là lời giải thích âm thanh kỳ lạ tròn ... nhưng tôi biết những gì bạn có ý nghĩa :-) - Kris
@ Kris ty cho nhận xét tôi đã nhận những gì bạn có nghĩa là :). Đã chỉnh sửa câu trả lời một chút :). - Willmore
Không liên quan đến câu hỏi, nhưng nó kỳ lạ về mặt ngữ nghĩa null instanceof Void trả về false xD - Jai


Các instanceof toán tử không cần rõ ràng null kiểm tra, vì nó không ném NullPointerException nếu toán hạng là null.

Vào thời gian chạy, kết quả của instanceof toán tử là true nếu giá trị của biểu thức quan hệ không null và tham chiếu có thể được truyền tới loại tham chiếu mà không cần đưa ra một ngoại lệ lớp học.

Nếu toán hạng là null, các instanceof toán tử trả về false và do đó, kiểm tra null rõ ràng là không cần thiết.

Hãy xem xét ví dụ bên dưới,

public static void main(String[] args) {
         if(lista != null && lista instanceof ArrayList) {                     //Violation
                System.out.println("In if block");
         }
         else {
                System.out.println("In else block");
         }
}

Cách sử dụng chính xác của instanceof như hình dưới đây,

public static void main(String[] args) {
      
         if(lista instanceof ArrayList){                     //Correct way
                  System.out.println("In if block");
         }
            else {
                 System.out.println("In else block");
         }  
}

2
2018-04-01 08:09





Cũng giống như một miếng ngon:

Cũng (((A)null)instanceof A) sẽ trở lại false.


(Nếu in ấn null có vẻ ngạc nhiên, đôi khi bạn phải làm điều đó, ví dụ trong các tình huống như thế này:

public class Test
{
  public static void test(A a)
  {
    System.out.println("a instanceof A: " + (a instanceof A));
  }

  public static void test(B b) {
    // Overloaded version. Would cause reference ambiguity (compile error)
    // if Test.a(null) was called without casting.
    // So you need to call Test.test((A)null) or Test.test((B)null).
  }
}

Vì thế Test.test((A)null) sẽ in a instanceof A: false.)


Tái bút: Nếu bạn đang thuê, xin vui lòng không sử dụng điều này như một câu hỏi phỏng vấn xin việc. : D


2
2018-03-22 12:11