2008-08-19 51 views
19

Tôi luôn nghĩ rằng phương thức .equals() trong java nên được ghi đè để được tạo riêng cho lớp bạn đã tạo. Nói cách khác để tìm kiếm sự tương đương của hai cá thể khác nhau thay vì hai tham chiếu đến cùng một cá thể. Tuy nhiên tôi đã gặp phải các lập trình viên khác dường như nghĩ rằng hành vi đối tượng mặc định nên được để lại một mình và một phương pháp mới được tạo ra để kiểm tra sự tương đương của hai đối tượng của cùng một lớp.Ghi đè phương thức bằng so với phương pháp mới

Đối số cho và chống lại việc ghi đè phương thức bằng?

Trả lời

19

Trọng equals phương pháp là cần thiết nếu bạn muốn kiểm tra tính tương đương trong các lớp thư viện chuẩn (ví dụ, đảm bảo một java.util.Set chứa các phần tử duy nhất hoặc sử dụng các đối tượng như các khóa trong các đối tượng java.util.Map).

Lưu ý, nếu bạn ghi đè bằng, đảm bảo bạn tôn trọng hợp đồng API như được mô tả trong tài liệu. Ví dụ, đảm bảo bạn cũng ghi đè Object.hashCode:

Nếu hai vật đều bình đẳng theo equals phương pháp (Object), sau đó gọi phương thức hashCode trên mỗi hai đối tượng phải xuất trình kết quả tương tự số nguyên .

CHỈNH SỬA: Tôi không đăng câu trả lời hoàn chỉnh về chủ đề này, vì vậy tôi sẽ lặp lại tuyên bố của Fredrik Kalseth rằng việc ghi đè bằng hoạt động tốt nhất cho immutable objects. Để báo giá API cho Map:

Lưu ý: cần lưu ý cẩn thận nếu đối tượng có thể thay đổi được sử dụng làm khóa bản đồ. Hành vi của bản đồ không được chỉ định nếu giá trị của một đối tượng được thay đổi theo cách ảnh hưởng tương đương với so sánh trong khi đối tượng là một phím trên bản đồ.

+2

Chương Java hiệu quả (Josh Bloch; phiên bản thứ nhất) về phương pháp java.lang.Object: http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf – McDowell

0

Phương thức bằng được dùng để so sánh các tham chiếu. Vì vậy, nó không nên được overriden để thay đổi hành vi của nó.

Bạn nên tạo một phương pháp mới để kiểm tra tính tương đương trong trường hợp khác nhau nếu bạn cần (hoặc sử dụng các phương pháp CompareTo trong một số lớp học NET)

0

Bạn chỉ nên cần phải ghi đè phương pháp equals() nếu bạn muốn hành vi cụ thể khi thêm các đối tượng cấu trúc dữ liệu được sắp xếp (SortedSet vv)

Khi bạn làm điều đó bạn cũng nên ghi đè hashCode().

Xem here để được giải thích đầy đủ.

8

Tôi rất muốn khuyên bạn nên chọn một bản sao của Java hiệu quả và đọc qua mục 7 tuân theo equals contract. Bạn cần phải cẩn thận nếu bạn ghi đè bằng đối tượng có thể thay đổi, vì nhiều bộ sưu tập như Bản đồ và Bộ sử dụng bằng để xác định tương đương và việc biến đổi đối tượng chứa trong bộ sưu tập có thể dẫn đến kết quả không mong muốn. Brian Goetz cũng có một số khá tốt overview of implementing equals and hashCode.

4

Bạn nên "không bao giờ" ghi đè bằng & getHashCode cho các đối tượng có thể thay đổi - điều này xảy ra với cả .net và Java cả hai. Nếu bạn làm, và sử dụng một đối tượng như là chìa khóa trong f.ex từ điển và sau đó thay đổi đối tượng đó, bạn sẽ gặp rắc rối vì từ điển dựa vào mã băm để tìm đối tượng.

Dưới đây là một bài viết tốt về chủ đề này: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

0

Thành thật mà nói, trong Java không có thực sự một cuộc tranh cãi với trọng bằng với. Nếu bạn cần so sánh các trường hợp bình đẳng, thì đó là những gì bạn làm.

Như đã đề cập ở trên, bạn cần phải nhận thức của hợp đồng với hashCode, và tương tự, xem ra cho các gotchas xung quanh giao diện Comparable - trong hầu hết các tình huống bạn muốn đặt hàng tự nhiên theo quy định của So sánh với được phù hợp với bằng (xem doc BigDecimal api cho ví dụ quầy kinh điển)

Tạo một phương pháp mới cho việc quyết định sự bình đẳng, hoàn toàn ngoài không làm việc với các lớp thư viện hiện có, ruồi khi đối mặt với ước Java hơi.

2

@David Schlosnagle mentions đề cập đến số Effective Java của Josh Bloch - đây là phải đọc cho bất kỳ nhà phát triển Java nào.

Có vấn đề liên quan: đối với các đối tượng giá trị không thay đổi, bạn cũng nên xem xét ghi đè compare_to. Từ ngữ tiêu chuẩn nếu chúng khác nhau nằm trong số Comparable API:

Thường thì trường hợp này, nhưng không hoàn toàn bắt buộc (so sánh (x, y) == 0) == (x.equals (y)) . Nói chung, bất kỳ người so sánh nào vi phạm điều kiện này phải chỉ rõ thực tế này. Ngôn ngữ được đề xuất là "Lưu ý: trình so sánh này áp đặt các thứ tự không phù hợp với bằng."

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