2012-05-14 26 views
31

Tôi đã kiểm tra mã nguồn của Object lớp học, nơi tôi thấy rằng phương pháp kê khai của getClass()Tại sao phương thức gốc hashCode() và getClass()?

public final native Class<?> getClass(); 

Và tuyên bố hashCode()

public native int hashCode(); 

Tại sao hai phương pháp này native phương thức trong lớp và làm thế nào tôi có thể lấy mã nguồn của các phương thức đó?

+13

không trùng lặp - OP biết nội dung gốc là gì, nhưng muốn biết _why_ hai phương pháp này cụ thể là gì. – Alnitak

+5

hashCode() có nguồn gốc vì cách thức dữ liệu được lưu trữ có thể khác nhau trên các hệ điều hành không giống nhau. Tôi không chắc chắn tại sao getClass() là mặc dù; có thể do sự triển khai khác nhau của đa hình. – Vulcan

+1

@Vulcan getClass() là cuối cùng, do đó bạn không thể ghi đè lên và phá vỡ hệ thống kiểu. – EJP

Trả lời

35

Bạn có thể tìm thấy toàn bộ mã nguồn của các phương pháp tự nhiên here

Tôi hy vọng điều này sẽ làm việc cho bạn.

Đây là những phương pháp gốc, vì nó phải tương tác với máy. Ở đây mã máy phụ thuộc được viết bằng ngôn ngữ C, không có trong gói nguồn hoặc trong rt.jar của vị trí lib của Java Runtime Environment (JRE).

Một lý do nữa để trở thành người bản địa có thể là vì lý do hiệu suất. Do hiệu suất lập trình cấp C có thể được cải thiện, do đó họ có thể đã viết mã gốc bằng ngôn ngữ C.

Các phương pháp có nguồn gốc vì chúng liên quan đến dữ liệu gốc. Phương thức hashCode trả về một giá trị số nguyên phụ thuộc vào biểu diễn bên trong của một con trỏ tới một đối tượng trên heap. Phương pháp getClass phải truy cập vào nội bộ vtbl (virtual function table) đại diện cho phân cấp lớp của chương trình đã biên dịch. Không thể thực hiện điều này với Java lõi.

+1

'Phương thức hashCode trả về một giá trị số nguyên phụ thuộc vào biểu diễn bên trong của một con trỏ tới một đối tượng trên heap.' Điều đó dường như không phải là trường hợp nhìn vào [source] (http: //hg.openjdk. java.net/jdk8/jdk8/hotspot/file/tip/src/share/vm/runtime/synchronizer.cpp#l555). –

+0

@BrianAgnew Xin chào, tôi đã cập nhật mã –

2

Thông tin cho các mục này nằm trong tiêu đề (cho lớp) hoặc ở nơi khác (đối với mã băm) Đây không phải là thứ bạn có thể triển khai trong Java. Nguồn cho các phương thức này nằm trong nguồn cho JVM. ví dụ. bạn có thể tải xuống mã nguồn cho OpenJDK.

29

Mã nguồn cho lớp đối tượng có thể được tìm thấy here

nguồn này chứa thi hành getClass() phương pháp (Xem dòng 58). hashCode được định nghĩa là hàm JVM_IHashCode (xem dòng 43).

JVM_IHashCode được xác định trong jvm.cpp. Xem mã bắt đầu từ dòng 504. Điều này lần lượt gọi ObjectSynchronizer :: FastHashCode được định nghĩa trong synchronizer.cpp. Xem việc triển khai FastHashCode tại dòng 576 và get_next_hash tại dòng 530.

Có thể, các phương pháp này có nguồn gốc cho hiệu suất và do các vấn đề thực tế khi triển khai.

Ví dụ: Từ javadocs, hashCode thường được triển khai "bằng cách chuyển đổi địa chỉ nội bộ của đối tượng thành số nguyên". Địa chỉ nội bộ này không có sẵn thông qua java sdk và sẽ phải được triển khai như một phương thức gốc.

Vui lòng đọc Is it possible to find the source for a Java native method?. Cũng đọc bài đăng trên blog này Object.hashCode implementation. Nó cung cấp thêm chi tiết. Nhưng thực hiện một xác nhận sai rằng hashCode không được tạo ra từ danh tính của đối tượng.

Hy vọng điều đó sẽ hữu ích.

+0

Vậy làm thế nào chúng ta có thể nói rằng JVM là nền tảng độc lập? –

+0

Làm thế nào điều này sẽ phá vỡ nền tảng độc lập? Đối với bất kỳ đối tượng nào, hashCode không bắt buộc phải giống nhau trên các nền tảng. Đối với vấn đề đó, nó thậm chí sẽ không giống nhau trên cùng một nền tảng, qua các lần chạy khác nhau. Hãy thử lớp công khai TestHashCode { chính void công cộng chính (String [] args) { Đối tượng o = new Object(); System.out.println (o.hashCode()); } } – krishnakumarp

+1

@BhavikAmbani Đây là thuật ngữ nitpicking, nhưng * JVM * không phải là nền tảng độc lập, mà là phần phụ thuộc nền tảng, thực thi nền tảng Java độc lập bytecode trên một nền tảng nhất định. – hyde

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