2012-06-16 38 views
5

Tôi biết khi nào chúng ta đang truyền các đối tượng, chúng ta đang truyền tham chiếu của nó như một giá trị. Nhưng giá trị này bạn nhận được là sử dụng phương pháp hashcode() đúng (theo các bài kiểm tra của tôi nó giống nhau)? Vì hashcode() không phải là địa chỉ bộ nhớ và không được đảm bảo để nhận các giá trị duy nhất mọi lúc, có thể có những điều kỳ lạ xảy ra như va chạm khi truyền vật thể không?điều gì thực sự xảy ra khi truyền các đối tượng trong java?

(Giả sử hashcode() đã không được ghi đè, tức là, nó sẽ trả về giá trị tương tự như System.identityHashCode())

Ba rất nhiều giống như câu hỏi này, nhưng tôi không thể tìm thấy một nguồn tài nguyên có liên quan mà discuses rằng giá trị con người là những gì được thông qua và làm thế nào để bạn có được nó?

EDIT: Đây là thử nghiệm của tôi. Giá trị mặc định toSting() sử dụng hashCode() bên trong và chuyển đổi nó thành giá trị hex. Vì vậy, khi chúng tôi đang đi qua các đối tượng, là giá trị này được thông qua? Hoặc những gì hiện java làm để theo dõi tất cả các đối tượng (được thông qua) vì vậy sẽ không có bất kỳ va chạm tham chiếu ?

Object o = new Object(); 
System.out.println(o); 
System.out.println(o.toString()); //both prints same thing - [email protected] 

Trả lời

6

hashcode() không liên quan đến bất kỳ cách nào với bộ nhớ trong của Java. Nó chỉ là một phương thức được cho là trả về một giá trị duy nhất có thể đại diện cho một đối tượng.

Bây giờ, nó chỉ như vậy xảy ra là cách tốt nhất để có được một giá trị duy nhất để đại diện cho một đối tượng là sử dụng địa chỉ bộ nhớ trong của nó. Và đó là điều thực hiện mặc định của hashcode(). Nhưng thực tế là hashcode()sử dụng một địa chỉ bộ nhớ không không nghĩa là hashcode()định nghĩa địa chỉ bộ nhớ.

+0

Như bạn nói nếu việc thực hiện mặc định trả về địa chỉ bộ nhớ thì không có vấn đề gì. Nhưng những gì tôi đã thấy là nó là (chức năng mặc định) không được bảo đảm để trả lại địa chỉ bộ nhớ. Nhưng một lần nữa những gì sau đó sẽ xảy ra khi có nhiều đối tượng hơn 2^32 và hashcode() trả về một số nguyên là 32 bit ?? – KillBill

+0

@ user601L 'hashcode()' không phải là một phương pháp dễ dàng. Đôi khi có va chạm. Nhưng nó sẽ luôn luôn tìm thấy một số giá trị để trả lại cho bạn, bất kể nó có sử dụng địa chỉ bộ nhớ của nó để có được nó hay không. Bạn thực sự không nên lo lắng về nó nhiều, chỉ biết rằng va chạm là có thể trong các trường hợp cạnh. –

+0

@bohemian Cảm ơn bạn đã sửa ngữ pháp của mình. Tôi là một thằng ngốc. –

2

Nhưng giá trị này bạn nhận được bằng cách sử dụng hashcode() phương pháp đúng (theo thử nghiệm của tôi nó giống nhau)?

số

Từ JSL:

Các giá trị tham chiếu (thường chỉ tham khảo) là con trỏ đến những đối tượng, và một tham chiếu null đặc biệt, trong đó đề cập đến không có đối tượng.

đọc trang này từ Harnessing Java

2

Việc thực hiện mặc định của hashcode cho Object trong java được dựa trên địa chỉ bộ nhớ của đối tượng, đó cũng là những gì tham chiếu là được.

Điều này không có nghĩa là hashCode() được gọi để nhận tham chiếu. Đây không phải là những gì xảy ra. Biến tham chiếu chỉ giữ địa chỉ bộ nhớ sau khi nó nhận được nó từ một instantiation (new Whatever()). Trong thực tế, nó phổ biến cho việc triển khai lớp để ghi đè hashcode() để làm điều gì đó khác biệt.

+7

Việc triển khai mặc định không trả lại địa chỉ bộ nhớ. Các máy ảo Java thường xuyên di chuyển các đối tượng xung quanh trong giai đoạn [compact] (http://en.wikipedia.org/wiki/Mark-compact_algorithm) của việc thu thập rác, do đó việc sử dụng địa chỉ bộ nhớ sẽ làm cho 'System.identityHashCode' không ổn định. –

1

Trong JavaObjects được chuyển bằng phương tiện tham chiếu khi bạn vượt qua Object thực sự bạn đã vượt qua tham chiếu Đối tượng gốc. Mã băm phụ thuộc vào các giá trị trường được liên kết với Đối tượng đó. hashcode là không có gì để làm với thực memory address. nó là rất hiếm hoi mà hai đối tượng với cùng một giá trị có khác nhau hashcode. Ngay cả khi bạn tạo hai đối tượng khác nhau nhưng có cùng giá trị hashcode của chúng sẽ giống nhau tùy thuộc vào hàm băm của bạn hiệu quả như thế nào

+0

Tôi đang nói về hashcode mặc định() ở đây, hoặc system.identityhashcode(). – KillBill

2

Không yêu cầu hoặc mong đợi rằng hashCode() là duy nhất. Đó là không phải là một phương pháp nhận dạng.

Tuy nhiên, phần lớn JDK mong đợi rằng nếu a.equals(b), thì a.hashCode() == b.hashCode().

Đảo ngược không bao giờ được mong đợi; tức là nếu !a.equals(b) thì đó là không phải yêu cầu a.hashCode() != b.hashCode(). Tuy nhiên, hiệu suất sẽ bị ảnh hưởng nếu đây không phải là thường là trường hợp. Nói cách khác, hashCode() được dự kiến ​​sẽ có ít va chạm.

Việc thực hiện mặc định hashCode() trong lớp Object thường sử dụng địa chỉ bộ nhớ để tạo các hashCode(), nhưng nó không trở lại địa chỉ, cũng không phải là không có yêu cầu trong spec ngôn ngữ để làm điều này.

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