2011-04-27 32 views
21

Tôi tìm thấy một vị trí trong một số mã tôi đang làm việc trên nơi null được truyền đến Object khi nó được chuyển đến một phương pháp.Tại sao bỏ null vào Object?

Tại sao điều này sẽ được thực hiện?

Tôi biết về this question đề cập đến các phương thức quá tải và sử dụng dàn diễn viên để xác định phiên bản của phương thức cần gọi. Nhưng nếu dàn diễn viên không được thực hiện, sẽ không phải là phương pháp quá tải với tham số được gõ là Object được chọn trên bất kỳ phiên bản kết hợp nào khác của phương thức nếu phương thức được gọi với đối số null không? Không. Vì vậy, các diễn viên khác thực hiện những gì?

+0

có thể trùng lặp của [Tại sao null truyền?] (Http://stackoverflow.com/questions/315846/why-null-cast) –

Trả lời

38

Nếu dàn diễn viên được chọn không, thì phiên bản cụ thể nhất sẽ được chọn.

null có thể là tham chiếu không thuộc loại String hoặc loại Object. Vì vậy, nếu hai phương thức đó có sẵn, thì phương thức String sẽ được gọi.

Nếu bạn có phương pháp với Object, IntegerString sau đó gọi rằng với null (và không có dàn diễn viên) sẽ cung cấp cho một lỗi biên dịch vì IntegerString đều hợp lệ và không kém phần đặc biệt (tức là không là một chuyên môn của cai khac). Trong trường hợp đó, bạn sẽ để truyền null để chỉ định phương thức cần gọi.

+0

Mặc dù tôi đồng ý với câu trả lời của bạn nhưng tôi tin rằng câu lệnh đầu tiên không được đặt đúng, tức là trình biên dịch luôn cố gắng xác định vị trí phù hợp nhất nếu có nhiều phương pháp được áp dụng, ví dụ, nếu bạn bỏ null để nói Integer và bạn đã nạp chồng phương thức với đối tượng kiểu và kiểu số đối số tương ứng sau đó nó sẽ giải quyết một với loại số (tức là một trong những cụ thể nhất). – sactiw

-2

"Nhưng nếu các diễn viên đã không được thực hiện, sẽ không phải là một phương pháp quá tải với một tham số gõ như Object được lựa chọn trên bất kỳ phiên bản phù hợp khác của phương pháp này nếu phương pháp này được gọi với một đối số null?"

Không, bởi vì 'null' không có loại - bạn sẽ gặp lỗi biên dịch.

+4

Sai. Bạn ** chỉ ** nhận được một lỗi biên dịch nếu có quá một "quá tải" cụ thể xung quanh. –

+0

Tôi đã lấy nó như là giả định rằng ông đã có nhiều hơn một phương pháp, đó là loại nhúng trong câu hỏi. – cbz

14

Phương thức "Object" luôn là phương pháp "ít cụ thể nhất" trong số tất cả "phương pháp áp dụng". Đó là lý do tại sao nó sẽ không được lựa chọn bởi trình biên dịch.

Nếu bạn chạy

String.valueOf(null); 

Sau đó, trình biên dịch có sự lựa chọn của hai "phương pháp được áp dụng". Bạn đang thực sự gọi phương thức cụ thể hơn

String.valueOf((char[]) null); 

Điều này sẽ cung cấp cho bạn NullPointerException. Để gọi phương thức khác, hãy viết

String.valueOf((Object) null); 

Trong trường hợp này, bạn chỉ có một "phương pháp áp dụng", vì vậy bạn không gặp vấn đề về phương pháp quá tải khác "cụ thể hơn".

+0

+1 cho 'String.valueOf (Object o)' là "ít nhất là cụ thể" phù hợp với tất cả các trận đấu có thể. Tuy nhiên, nó sẽ có ý nghĩa cũng đề cập rằng trong trường hợp String nếu không có diễn viên cụ thể được thực hiện sau đó phù hợp nhất "cụ thể" chúng tôi đang còn lại là 'String.valueOf (Char [] c)' và do đó nó được gọi. ** Lưu ý: ** Trình biên dịch java luôn giải quyết các phương thức quá tải cho một phương thức có kết quả "cụ thể nhất" và nếu nó không thực hiện được thì nó sẽ cung cấp tham chiếu đến phương thức là lỗi biên dịch của ambiguos. – sactiw

+0

@sactiw: Cảm ơn gợi ý. Có, tôi đã nhập sai 'char []' so với 'byte []' ở đó ... –

0

Mặc dù câu trả lời trước đó đã giải thích điều gì sẽ xảy ra nếu bạn bỏ null vào đối tượng so với nếu bạn không bỏ trống đối tượng, nhưng tôi vẫn muốn thêm vài điểm bị thiếu.

Vì vậy, trong Java, 'mảng' là các đối tượng có nghĩa là chúng có thể được gán cho loại Đối tượng tức lànếu bạn làm new char[0].getClass().getSuperclass(), nó sẽ cho java.lang.Object và do đó trong trường hợp khi null không được trình biên dịch rõ ràng, hãy chọn valueOf(char[]) trên phương thức áp dụng nhất là valueOf(Object).

Tuy nhiên, ở đây có phần thiếu, đã có được một phương pháp quá tải đã được chấp nhận một kiểu giao diện param (nhớ giao diện không mở rộng lớp Object nên họ cũng gây ra sự nhập nhằng trong việc lựa chọn phương pháp cụ thể nhất) ví dụ valueOf (CharSequence) sau đó điều này sẽ dẫn đến lỗi biên dịch thời gian (tức là tham chiếu đến valueOf là mơ hồ) bởi vì trình biên dịch không thể chọn phương thức thích hợp nhất.

Vì vậy, dòng dưới cùng là tránh truyền null thô làm đối số cho các phương thức chứ không phải luôn đặt chúng thành loại param của phương thức được gọi. :)

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