2013-07-12 28 views
5

Cách JVM chọn phương pháp nào để thực thi?Lựa chọn phương pháp có quá tải và ghi đè

Có đúng là quy trình chọn được chia thành 2 phần. Đầu tiên trong khi biên dịch JVM, hãy tìm một phương thức ứng cử viên để thực thi. Nó chọn chữ ký cần thiết vào lớp đối tượng được khai báo (không phải là lớp đối tượng hiệu quả). Khi nó đã chọn chữ ký ứng cử viên, nó bắt đầu tìm kiếm nó trong hệ thống phân cấp bắt đầu từ lớp hiệu quả của đối tượng.
Điều này có đúng không?

Thêm một câu hỏi:

Đây là một hệ thống phân cấp các lớp học và phương pháp liên quan:

- Class A: +f(short x): int; +f(String x): int; 
- Class B extends A: +f(int x): int; +f(String x): int; 
- Class C extends A: +f(double x): int; +f(byte x): int; 
- Class D extends C: +f(byte x): int; +f(short x): int; 
- Class E extends C: +f(char x): int; +f(int x): int; 

Vì vậy:

  • A là lớp cha cho B và C
  • B là lớp con của A
  • C là phân lớp của A
  • C là lớp cha cho D và E
  • D và E là C lớp con

Tất cả những lớp học chỉ có một phương pháp gọi là "f" với chữ ký nêu trên.

bây giờ tôi tuyên bố đối tượng sau:

A a = new D(); 
B b = new B(); 
C c = new E(); 

1. Tại sao phương pháp gọi a.f (3) không thể được xử lý và trả về một lỗi?

Nếu những gì tôi đã đề cập trước là chính xác đây là những gì nên xảy ra:

Các JVM nhìn vào Class A cho một phương pháp với f chữ ký (int x) hoặc bất kỳ chữ ký tương thích (với đúc). Nó tìm phương thức f (short x) cần tương thích, đúng không? Sau đó, nó sẽ cho chữ ký này rất chính xác vào lớp D, và nó tìm thấy nó thực hiện các D: f (ngắn x). Theo cuốn sách của tôi, điều này không đúng, tại sao? Nó có thể là vì ngắn không thực sự là một khuyến mãi cho int và do đó JVM không xem xét f (ngắn x) phù hợp cho cuộc gọi? Và do đó sẽ không tìm thấy bất kỳ phương pháp f nào tương thích và sẽ trả về lỗi.

Tôi đã kiểm tra trên Google và trên bất kỳ tài nguyên nào khác mà tôi có thể tìm thấy (cũng trên Stackoverflow) nhưng tất cả đều rất rõ ràng và không đủ câu trả lời chi tiết, do đó tôi nghĩ có thể là một điều tốt để hỏi, tôi hy vọng nó sẽ biến câu trả lời sẽ hữu ích cho các sinh viên tương lai chiến đấu với quá tải và overridding :) Cảm ơn trước.

+1

Toàn bộ quá trình được mô tả trong các kỹ thuật Java Ngôn ngữ: http://docs.oracle.com/javase/specs/ jls/se7/html/jls-15.html # jls-15.12.2 –

+0

Cảm ơn đề xuất. Đây chắc chắn là tài liệu tôi đang tìm kiếm. – jnardiello

Trả lời

1

Hai phương pháp duy nhất có thể được gọi là:

Class A: +f(short x): int; +f(String x): int;

Để cho các diễn viên mới có giá trị chúng ta cần phải ngầm đúc số nguyên từ 3 đến hoặc là một đoạn ngắn hoặc một chuỗi.

Nhưng bạn không thể chuyển đổi hoàn toàn số nguyên 3 thành kích thước nhỏ hơn ngắn. Và tất nhiên nó không thể được ngầm đúc vào một chuỗi để nó không thể được xử lý.

Chỉnh sửa:

Vì bạn đặt một thể hiện của lớp D vào vùng chứa A, cá thể chỉ biết về phương pháp A. Bạn phải cast instance của a đến D để gọi các method của D mà sau đó sẽ cho phép bạn ngầm cast int 3 thành double và gọi phương thức f(double).

+0

Vâng, cảm ơn bạn đã trả lời câu hỏi thứ hai của tôi. Về thực tế rằng chỉ có hai phương pháp có thể được gọi là những người từ A, tôi không hoàn toàn chắc chắn tôi đã có những gì bạn có nghĩa là. – jnardiello

-2

Liên quan đến câu hỏi thứ hai của bạn (lý do tại sao các lỗi gọi phương thức)

Bạn đã đặt mình vào một vị trí mà bạn đã có bốn điều phức tạp bạn cần phải lo lắng về ở đây: quá tải, trọng, chuyển đổi kiểu dữ liệu và (có khả năng) autoboxing.

Điều thú vị nhất có thể thực sự là chuyển đổi. http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

Do quy tắc thừa kế, đối tượng một có các hoạt động sau:

f(byte) (from D) 
f(short) (from D) 
f(double) (from C) 
f(String) (from A) 

Nhưng vấn đề là, gọi chức năng này với giá trị 3 thực sự có nghĩa là "một hằng số nguyên của 3." Bạn không thể ngầm đưa một số nguyên vào một byte hoặc một chuỗi, vì đây là một chuyển đổi thu hẹp. Tuy nhiên, bạn có thể ngầm đúc một số nguyên thành một đôi hoặc một phao.

Vì vậy, tôi mong đợi af (3) để đánh giá f (double) từ C.

+0

Điều này là không đúng sự thật, một người không biết rằng một trường hợp của D do đó mà không đúc bạn không thể truy cập bất kỳ phương pháp khác mà không phải là trong A và cha mẹ của nó. – Grammin

+0

Xin chào Matt, cảm ơn bạn đã trả lời nhanh chóng và rõ ràng. Thật không may tôi có thể đảm bảo với bạn rằng nó sẽ không đánh giá C: f (double) -actually, nó sẽ không đánh giá tất cả trở về một lỗi - vì đối tượng là từ lớp A và trong quá trình biên dịch JVM sẽ tìm kiếm một chữ ký trong A, không phải trong C. Như trong A không có chữ ký rõ ràng, nó sẽ chỉ trả về một lỗi. Ít nhất đây là những gì tôi nghi ngờ. Nghi ngờ chính của tôi là: nó có thể được eval bằng cách sử dụng f (ngắn x) trong A? Ai đó đã trả lời rằng: Không, bạn không thể. – jnardiello