(...) nhưng khi chúng tôi sử dụng bất kỳ loại lớp Wrapper của các đối tượng được sử dụng nói rằng Integer như sau
Integer i = new Integer(10)
System.out.println(i);
là nó toString() có trách nhiệm in nó hay Unboxing ?
Bạn đang đi qua một Object
để println
do đó, nó rõ ràng là println(Object obj)
đó được gọi là mà viết đầu ra của String.valueOf(obj)
trong đó kêu gọi obj.toString()
nếu obj
không phải là null
.
PS: Không vi phạm nhưng, tại sao bạn không chỉ xem xét các nguồn?
Cập nhật: Tôi có thể đã bỏ lỡ điểm của câu hỏi (gây nhầm lẫn trong biểu mẫu hiện tại nếu tôi có thể). Trên thực tế, câu hỏi có thể là:
(...) nhưng khi chúng tôi sử dụng bất kỳ loại lớp Wrapper của các đối tượng được sử dụng nói giả sử Integer như sau
Integer i = new Integer(10)
System.out.println(i);
phương pháp nào sẽ được gọi là: println(Object)
hoặc println(int)
?
Nếu đây là câu hỏi, thì câu trả lời nằm trong khóa học là The Java Language Specification. Để đơn giản hóa, phương thức được gọi vào thời gian chạy sẽ là phương thức được xác định tại thời gian biên dịch. Bây giờ, trình biên dịch xác định phương thức sẽ được gọi ra như thế nào? Vâng, điều này được giải thích trong phần 15.12 Method Invocation Expressions. Tôi sẽ không bao gồm tất cả các chi tiết, spec này tốt hơn tôi nhưng, về cơ bản, bước đầu tiên là tìm lớp hoặc giao diện để tìm kiếm, bước thứ hai là tìm tất cả các phương pháp áp dụng và sau đó chọn cụ thể nhất phương pháp, bước thứ ba là để xác minh nếu phương pháp được chọn là thích hợp. Tôi sẽ tập trung vào bước thứ 2 (đó là bước thú vị ở đây). Như đã trình bày trong phần 15.12.2 Compile-Time Step 2: Determine Method Signature:
Một phương pháp được áp dụng nếu nó là một trong hai áp dụng bởi subtyping (§15.12.2.2), áp dụng bằng phương pháp gọi chuyển đổi (§15.12.2.3), hoặc nó là một phương pháp được áp dụng biến arity (§15.12.2.4).
Quy trình xác định khả năng áp dụng bắt đầu bằng cách xác định các phương pháp có khả năng áp dụng (§15.12.2.1). Phần còn lại của quy trình được chia thành ba giai đoạn.
Thảo luận
Mục đích của việc phân chia thành các giai đoạn là để đảm bảo khả năng tương thích với phiên bản cũ của các lập trình Java ngôn ngữ.
Giai đoạn đầu (§15.12.2.2) Thực hiện quá tải độ phân giải mà không phép đấm bốc hay unboxing chuyển đổi, hoặc sử dụng các biến arity phương pháp gọi. Nếu không có phương pháp áp dụng được tìm thấy trong giai đoạn này thì quá trình xử lý tiếp tục đến giai đoạn thứ hai là .
Thảo luận
Điều này đảm bảo rằng bất kỳ cuộc gọi mà là hợp lệ trong các phiên bản cũ của ngôn ngữ không được coi là mơ hồ như là kết quả của sự ra đời của phương pháp arity biến, tiềm ẩn đấm bốc và/hoặc unboxing.
Giai đoạn thứ hai (§15.12.2.3) Thực hiện quá tải độ phân giải khi phép boxing và unboxing, nhưng vẫn ngăn cản việc sử dụng các biến arity phương pháp gọi. Nếu không có phương pháp áp dụng được tìm thấy trong giai đoạn này thì việc xử lý tiếp tục đến giai đoạn thứ ba là .
Thảo luận
này đảm bảo rằng một biến phương pháp arity không bao giờ được gọi nếu một áp dụng phương pháp arity cố định tồn tại.
Giai đoạn thứ ba (§15.12.2.4) cho phép quá tải phải được kết hợp với các phương pháp arity biến, boxing và unboxing .
Quyết định liệu một phương pháp là áp dụng ý chí, trong trường hợp của phương pháp chung (§8.4.4), yêu cầu đối số loại thực tế được xác định . Đối số loại thực tế có thể được chuyển một cách rõ ràng hoặc ngầm. Nếu chúng được chuyển hoàn toàn, chúng phải được phỏng đoán (§15.12.2.7) từ các loại biểu thức đối số .
Nếu áp dụng một số phương pháp đã được xác định trong một trong những ba giai đoạn thử nghiệm khả năng ứng dụng, thì một cụ thể nhất được chọn, theo quy định tại phần §15.12.2.5. Xem các phần phụ sau đây cho chi tiết .
Trong trường hợp đặc biệt này, println(Obj)
được áp dụng bởi subtyping (và println(int)
sẽ được áp dụng bằng cách chuyển đổi gọi là boxing/unboxing là một chuyển đổi (§5.3)). Vì vậy trình biên dịch sẽ nhập phase 1. Và nếu chúng ta nhìn vào câu cuối cùng:
Nếu không tìm thấy phương pháp áp dụng bằng cách phân loại, tìm kiếm các phương pháp áp dụng tiếp tục với giai đoạn 2 (§15.12.2.3). Nếu không, phương pháp cụ thể nhất (§15.12.2.5) được chọn trong số các phương pháp được áp dụng theo loại phụ.
Ở đây, không có bất kỳ phương pháp khác được áp dụng bởi subtyping vì vậy đây là kết thúc, println(Object)
sẽ được gọi (và do đó toString()
sẽ được gọi, để trả lời câu hỏi ban đầu).
Tôi nghĩ rằng nó sẽ chỉ unbox trong trường hợp int là lựa chọn duy nhất. Vì có một println (Object), có lẽ nó sẽ được gọi. –
@gurukulki, được cập nhật bằng câu trả lời hy vọng nó sẽ giúp. –