2009-07-15 31 views
5

Tôi đang gặp khó khăn khi hiểu câu hỏi này và giải thích câu trả lời cho câu hỏi tự kiểm tra SCJP 1.6. Đây là vấn đề:Var-arg của mảng đối tượng so với mảng đối tượng - cố gắng hiểu câu hỏi tự kiểm tra SCJP

class A { } 
class B extends A { } 
public class ComingThru { 
    static String s = "-"; 
    public static void main(String[] args) { 
     A[] aa = new A[2]; 
     B[] ba = new B[2]; 
     sifter(aa); 
     sifter(ba); 
     sifter(7); 
     System.out.println(s); 
    } 
    static void sifter(A[]... a2) { s += "1"; } 
    static void sifter(B[]... b1) { s += "2"; } 
    static void sifter(B[] b1) { s += "3"; } 
    static void sifter(Object o) { s += "4"; } 
} 

Kết quả là gì? Câu trả lời là -434, nhưng những gì ném tôi ra là giải thích của cuốn sách. Nó hoàn toàn khác với cách khái niệm được giải thích trước đó trong chương.

"Nói chung, quá tải var-args phương pháp được lựa chọn cuối cùng. Hãy nhớ rằng mảng là đối tượng. Cuối cùng, một int có thể được đóng hộp đến một Integer và sau đó 'mở rộng' cho một đối tượng."

Tách lên, ai đó có thể vui lòng xác định thêm giải thích đó?

  1. Nói chung, các phương pháp var-arg bị quá tải được chọn cuối cùng.
  2. Mảng là đối tượng (tôi thực sự hiểu điều đó, nhưng tại sao lại liên quan đến câu hỏi này).
  3. Một int có thể được đóng hộp đến một số nguyên và sau đó "mở rộng" cho một đối tượng.

Cảm ơn!

Trả lời

6

Cuốn sách đang cố gắng giải thích tại sao hai lần quá tải đầu tiên không bao giờ được chọn: vì điểm đánh dấu var-args ... làm cho chúng chỉ được sử dụng nếu mọi quá tải có thể không thành công. Trong trường hợp này, điều này không xảy ra - hai câu bắt đầu bằng "Remember" giải thích tại sao nó không xảy ra, tại sao có thể có quá tải khác trong trường hợp đầu tiên và cuối cùng (trường hợp thứ hai và khớp với quá tải thứ 3) của sifter là hiển nhiên): một mảng là một đối tượng, và một int có thể được đóng hộp sau đó mở rộng đến một đối tượng, do đó, quá tải thứ 4 phù hợp với những người đầu tiên và cuối cùng của các cuộc gọi để sàng lọc.

+0

Cảm ơn lời giải thích tuyệt vời! –

+0

@ hal100001, luôn sẵn sàng trợ giúp - khi tất cả các câu trả lời đều được ghi nhớ, hãy nhớ chọn lựa tốt nhất/hữu ích nhất để chấp nhận (như bạn nói, msaeed cũng rất hữu ích - chúng tôi đang nói về cơ bản những điều tương tự của khóa học nhưng biểu hiện của tôi thì thông tục hơn, của anh ấy, có cấu trúc hơn). –

4
  1. Khi cố gắng để xác định phương pháp để gọi, trình biên dịch đầu tiên tìm kiếm những phương pháp vararg không (ví dụ sifter(Object)) trước khi xem xét một vararg một (ví dụ sifter(A[]...)), khi cả hai phương pháp thuộc về cùng lớp (thêm hoặc ít hơn).

  2. Vì mảng là Object, việc gọi sifter(aa) sẽ khớp với sifter(Object), do đó thậm chí không xem xét sifter(A[]...).

  3. Bắt đầu từ Java 5, trình biên dịch có thể "hộp" nguyên thủy, tức là chuyển đổi giá trị nguyên thủy (ví dụ: int) thành Object tương ứng (ví dụ: Integer). Vì vậy, đối với sifter(6), trình biên dịch chuyển đổi int 6 thành một Integer 6, do đó nó sẽ khớp với phương pháp sifter(Object).

+0

Giải thích tuyệt vời. Cảm ơn!!! –

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