2016-01-12 21 views
5

Bạn có thể giải thích cho tôi tại sao kết quả là "int" không? Tôi hy vọng nó sẽ được "dài" cung cấp biến là một byte.Phỏng vấn mở rộng nguyên thủy Java

public class Test{ 
     public static void printValue(int i, int j, int k){ 
      System.out.println("int"); 
     } 

     public static void printValue(byte...b){ 
      System.out.println("long"); 
     } 

     public static void main(String... args){ 
      byte b = 9; 
      printValue(b,b,b); 
     } 
} 

Trả lời

12

Trình biên dịch Java phải chọn giữa hai phương thức khớp. Nó sẽ luôn luôn chọn một phương thức không sử dụng biến số (varargs) trên một phương thức không sử dụng nó. Nó sẽ thúc đẩy tất cả 3 đối số đến int để khớp với số printValue đầu tiên so với varargs sử dụng.

Section 15.12.2 of the JLS trạng thái:

Phần còn lại của quá trình này được chia thành ba giai đoạn, để đảm bảo khả năng tương thích với các phiên bản của ngôn ngữ lập trình Java trước khi Java SE 5.0. Các giai đoạn là:

  1. Giai đoạn đầu (§15.12.2.2) thực hiện Nghị quyết tình trạng quá tải mà không cho phép đấm bốc hoặc chuyển đổi unboxing, hay 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ứ hai.

Điều này đảm bảo rằng bất kỳ cuộc gọi đó là hợp lệ trong ngôn ngữ lập trình Java trước JDK 5.0 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, boxing ngầm và/hoặc unboxing. Tuy nhiên, việc khai báo một phương thức arity biến (§8.4.1) có thể thay đổi phương thức được chọn cho một biểu thức phương thức phương thức đã cho, bởi vì một phương thức arity biến được coi là một phương thức arity cố định trong giai đoạn đầu tiên. Ví dụ, khai báo m (Object ...) trong một lớp đã khai báo m (Object) làm cho m (Object) không còn được chọn cho một số biểu thức gọi (như m (null)), như m (Object []) cụ thể hơn.

  1. Giai đoạn thứ hai (§15.12.2.3) thực hiện độ phân giải quá tải trong khi cho phép boxing và unboxing, nhưng vẫn loại trừ việc sử dụng phương thức invity biến. 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.

Điều này đảm bảo rằng phương thức sẽ không bao giờ được chọn thông qua lời gọi phương thức xác thực biến thiên nếu nó được áp dụng thông qua lời gọi phương thức xác thực.

  1. Giai đoạn thứ ba (§15.12.2.4) cho phép quá tải được kết hợp với các phương pháp xác định biến số, quyền anh và unboxing.

(tôi nhấn mạnh đậm)

Một phương thức khớp (sự quá tải đầu tiên) được tìm thấy trong giai đoạn đầu, vì vậy trình biên dịch thậm chí không xem xét các giai đoạn thứ ba - cho phép phương pháp arity biến - - vì vậy int được in.

Một cách để chọn quá tải thứ hai (mà in ngược theo cách long) là tạo một mảng một cách rõ ràng để quá tải đầu tiên không thể khớp.

printValue(new byte[]{b,b,b}); 
-1

Xin chào kết quả là 'int' vì khi chạy hàm chính bạn không inValue với một đối số nhưng thay vì 3 đối số. do đó trình biên dịch giả định rằng bạn đang tham chiếu đến printValue đầu tiên có 3 tham số.Vì bạn không sử dụng các tham số này bên trong hàm tất cả mọi thứ khi không có bất kỳ lỗi thời gian chạy nào. Mặt khác tôi sẽ nói rằng thực hành không tốt để tìm loại biến theo cách này. Cách tốt nhất là sử dụng câu lệnh 'if else'. Và bạn có thể tham khảo bài đăng này để biết thông tin về cách tìm loại trong java: How do you know a variable type in java?

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