2015-06-15 17 views
13
public class test { 
    test(double[] a) 
    { 
     System.out.println("in double"); 
    } 
    test(Object a) 
    { 
     System.out.println("in object"); 
    } 
    public static void main(String args[]) 
    { 
     new test(null); 
    } 
} 

Trong đoạn mã trên, tôi vượt qua null làm đối số hàm tạo. Như null có thể là bất cứ điều gì, mã trên biên dịch tốt. Khi tôi chạy mã, tôi mong đợi nó in trong đối tượng nhưng nó in trong đôi Lý do đằng sau điều này là gì?Tại sao Java lại thích gọi hàm dựng kép?

LƯU Ý các câu hỏi liên quan có thể không trùng lặp vì câu hỏi này có liên quan với datatype nguyên thủy vs Object

+0

Dường như nó đang sử dụng 'double' vì nó là hàm tạo đầu tiên được định nghĩa. Bạn đã thử xác định hàm tạo với tham số 'Object' trước chưa? –

+1

@KErlandsson xin lỗi Tôi không nghĩ rằng một bản sao của câu hỏi được liên kết – rocking

+4

@rocking một đôi [] không phải là một nguyên thủy. Mảng là các đối tượng. 'double [] instanceof Object == true'. –

Trả lời

21

Lý do là Java diễn giải null như bất kỳ loại nào và khi chọn phương thức để gọi, nó sẽ chọn phương pháp cụ thể nhất đầu tiên loại đối số. Vì null có thể thuộc loại double[]double[]Object, trình biên dịch sẽ chọn phương thức mất double[]. Nếu các lựa chọn liên quan đến các loại có thể có liên quan như nhau nhưng không liên quan, ví dụ: double[]String, khi đó trình biên dịch sẽ không thể chọn phương thức và điều đó sẽ dẫn đến lỗi cuộc gọi phương thức không rõ ràng.

Các JLS, Section 4.1, khẳng định:

Các tham chiếu null luôn có thể được chỉ định hoặc bầu cho bất kỳ loại tài liệu tham khảo (§5.2, §5.3, §5.5).

Trong thực tế, lập trình viên có thể bỏ qua loại null và chỉ giả vờ rằng null chỉ là một chữ đặc biệt có thể thuộc bất kỳ loại tham chiếu nào.

+0

Nếu tôi tạo một hàm tạo khác chấp nhận gấp đôi [] và Số thì nó không biên dịch.những lý do gì? Tôi có phải sửa đổi câu hỏi của mình không? – rocking

+0

@rocking Lý do là không có 'double []' hay 'Số' nào cụ thể hơn nhau. 'double []' không phải là một phân lớp của 'Số', và' Số' không phải là một phân lớp của 'double []'. Không có "phương pháp cụ thể nhất", mặc dù cả hai phương pháp đều được áp dụng. Đó là nơi sự mơ hồ nảy sinh; trình biên dịch không biết cái nào để chọn, do đó, nó tạo ra một lỗi để thay thế. – rgettman

+0

double [] cũng không liên quan đến đối tượng tôi có nghĩa là nó không phải là lớp con của đối tượng vì double là kiểu nguyên thủy. do đó, theo câu trả lời của bạn là có 'Double' vs' Object 'thì nó sẽ chọn cho hầu hết các loại cụ thể, isnt? – rocking

9

Cả nhà xây dựng được áp dụng, vì null là mui trần cho cả Objectdouble[] - vì vậy trình biên dịch cần phải sử dụng quá tải độ phân giải để xác định hàm tạo nào cần gọi.

JLS 15.9.3 sử dụng JLS 15.12.2 để xác định chữ ký hàm tạo "cụ thể nhất" để sử dụng, dựa trên hàm tạo nào có loại thông số cụ thể nhất, theo JLS 15.12.2.5. Các chi tiết chính xác hơi mơ hồ (IMO) nhưng trong trường hợp này quy tắc cơ bản của ngón tay cái "nếu bạn có thể chuyển đổi từ T1 sang T2, nhưng không T2 đến T1, thì T1 là cụ thể hơn" là đủ tốt.

double[] là loại cụ thể hơn Object, bởi vì có chuyển đổi ẩn từ double[] thành Object, nhưng không ngược lại.

+0

bạn có thể cho tôi biết làm thế nào để xác định đó là loại cụ thể nhất? – rocking

+2

@rocking: Tôi đã đưa cho bạn một quy tắc về liên kết ngón tay cái và đặc điểm kỹ thuật ... Tôi không chắc bạn muốn gì khác. –

+0

Đây có phải là cùng một kịch bản hoạt động cho các phương pháp quá ?? –

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