Java Equals () 메소드를 우선적으로 재정의합니다 - 작동하지 않습니까?

StackOverflow https://stackoverflow.com/questions/185937

  •  06-07-2019
  •  | 
  •  

문제

나는 equals() 오늘날 잘 테스트 된 클래스라고 생각한 것은 충돌하고 추적하는 데 오랜 시간이 걸렸던 버그를 일으킨 방법입니다.

완전성을 위해, 나는 IDE 또는 디버거를 사용하지 않았습니다. 시간은 매우 제한적이었고 학교 프로젝트였습니다.

어쨌든 -

나는 포함 할 수있는 기본 쇼핑 카트를 개발하고있었습니다. ArrayListBook 사물. 구현하기 위해 addBook(), removeBook(), 그리고 hasBook() 카트의 방법, 나는 Book 이미 존재했습니다 Cart. 그래서 나는 간다 -

public boolean equals(Book b) {
    ... // More code here - null checks
    if (b.getID() == this.getID()) return true;
    else return false;
}

모두 테스트에서 잘 작동합니다. 나는 6 개의 객체를 만들고 데이터로 채 웁니다. 많은 추가, 제거, () 작업이 Cart 그리고 모든 것이 잘 작동합니다. 나는 당신이 할 수 있다는 것을 읽었습니다 어느 쪽이든 equals(TYPE var) 또는 equals(Object o) { (CAST) var } 그러나 그것이 효과가 있기 때문에 너무 중요하지 않다고 가정했습니다.

그런 다음 문제를 해결했습니다. Book 객체 그만큼 ID 책 수업 내에서. 다른 데이터는 입력되지 않습니다. 기본적으로 다음은 다음과 같습니다.

public boolean hasBook(int i) {
    Book b = new Book(i);
    return hasBook(b);
}

public boolean hasBook(Book b) {
    // .. more code here
    return this.books.contains(b);
}

갑자기, equals(Book b) 메소드가 더 이상 작동하지 않습니다. 좋은 디버거없이 추적하는 데 시간이 오래 걸렸습니다. Cart 클래스는 올바르게 테스트하고 정확했습니다. 스와핑 후 equals() 다음에 대한 방법 :

public boolean equals(Object o) {
    Book b = (Book) o;
    ... // The rest goes here   
}

모든 것이 다시 작동하기 시작했습니다. 이 방법이 책 매개 변수를 명확하게 받아들이지 않기로 결정한 이유가 있습니까? ~였다 Book 물체? 유일한 차이점은 동일한 클래스 내에서 인스턴스화되었으며 하나의 데이터 구성원으로 만 채워진 것 같습니다. 나는 매우 혼란 스럽습니다. 제발, 약간의 빛을 흘리나요?

도움이 되었습니까?

해결책

Java에서 equals() 상속 된 메소드 Object 이다:

public boolean equals(Object other);

다시 말해, 매개 변수는 유형이어야합니다. Object.

그만큼 ArrayList 올바른 평등 방법을 사용합니다. 여기서 항상 제대로 무시하지 않은 방법을 호출했습니다. Object동등합니다.

방법을 올바르게 무시하지 않으면 문제가 발생할 수 있습니다.

나는 매번 다음과 같다.

@Override
public boolean equals(Object other){
    if (other == null) return false;
    if (other == this) return true;
    if (!(other instanceof MyClass))return false;
    MyClass otherMyClass = (MyClass)other;
    ...test other properties here...
}

사용 @Override 주석은 바보 같은 실수로 톤을 도울 수 있습니다.

슈퍼 클래스 또는 인터페이스의 메소드를 재정의한다고 생각할 때마다 사용하십시오. 이렇게하면 잘못한 경우 컴파일 오류가 발생합니다.

다른 팁

Eclipse를 사용하면 상단 메뉴로 이동하십시오.

소스 -> equals () 및 hashcode () 생성

당신의 질문에 약간 주제가되었지만 어쨌든 언급 할 가치가있을 것입니다.

커먼즈 랭 Equals 및 해시 코드를 재정의하는 데 사용할 수있는 몇 가지 훌륭한 방법이 있습니다. 체크 아웃 equalsbuilder.reflectionequals (...) 그리고 HashcodeBuilder.reflectionhashcode (...). 과거에 나에게 많은 두통을 저장했습니다. 물론 ID에서 "동등한"을하고 싶다면 상황에 맞지 않을 수도 있습니다.

또한 사용해야한다는 데 동의합니다 @Override 주석을 우선시 할 때마다 (또는 다른 방법).

보일러 플레이트 코드를 저장하는 또 다른 빠른 솔루션은 다음과 같습니다 Lombok Equalsandhashcode 주석. 쉽고 우아하며 사용자 정의 할 수 있습니다. 그리고 IDE에 의존하지 않습니다. 예를 들어;

import lombok.EqualsAndHashCode;

@EqualsAndHashCode(of={"errorNumber","messageCode"}) // Will only use this fields to generate equals.
public class ErrorMessage{

    private long        errorNumber;
    private int         numberOfParameters;
    private Level       loggingLevel;
    private String      messageCode;

참조 옵션 평등에 사용할 필드를 사용자 정의 할 수 있습니다. Lombok은 avalaible입니다 Maven. 그냥 추가하십시오 제공 범위:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.14.8</version>
    <scope>provided</scope>
</dependency>

Android Studio에는 Alt + Insert ---> Equals 및 Hashcode가 있습니다.

예시:

    @Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Proveedor proveedor = (Proveedor) o;

    return getId() == proveedor.getId();

}

@Override
public int hashCode() {
    return getId();
}

고려하다:

Object obj = new Book();
obj.equals("hi");
// Oh noes! What happens now? Can't call it with a String that isn't a Book...

그만큼 instanceOf 진술은 종종 평등을 구현하는 데 사용됩니다.

이것은 인기있는 함정입니다!

문제는 사용하는 것입니다 instanceOf 대칭 규칙을 위반합니다.

(object1.equals(object2) == true) 경우에만 (object2.equals(object1))

첫 번째 평등이 참이고 Object2는 OBJ1이 속한 클래스의 서브 클래스 인스턴스 인 경우 두 번째 평등은 False를 반환합니다!

OB1이 속한 것으로 간주되는 클래스가 최종으로 선언 된 경우이 문제는 발생할 수 없지만 일반적으로 다음과 같이 테스트해야합니다.

this.getClass() != otherObject.getClass(); 그렇지 않은 경우, False를 반환하고 그렇지 않으면 평등을 비교하기 위해 필드를 테스트하십시오!

RecordId는 객체의 속성입니다

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Nai_record other = (Nai_record) obj;
        if (recordId == null) {
            if (other.recordId != null)
                return false;
        } else if (!recordId.equals(other.recordId))
            return false;
        return true;
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top