버그 찾기 경고:Equals 메소드는 인수 유형에 대해 어떤 것도 가정해서는 안 됩니다.

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

  •  21-08-2019
  •  | 
  •  

문제

내 프로젝트에서 FindBugs를 실행할 때 위에서 설명한 오류가 몇 가지 발생했습니다.

즉, 내 재정의 버전은 RHS 개체를 재정의 버전이 정의된 개체와 동일한 유형으로 캐스팅합니다.

그러나 AFAIK Java는 메소드 매개변수의 변화를 허용하지 않으므로 더 나은 디자인이 가능한지 확신할 수 없으므로 동등 매개변수에 대해 다른 유형을 정의할 수 없습니다.

내가 뭔가 아주 잘못하고 있는 걸까요, 아니면 FindBugs가 너무 열성적인 걸까요?

이 질문을 다른 방식으로 표현하면 다음과 같습니다.equals에 전달된 객체가 LHS와 동일한 유형이 아닌 경우 올바른 동작은 무엇입니까?이것은 거짓입니까, 아니면 예외가 있어야 합니까?

예를 들어:

public boolean equals(Object rhs)
{
    MyType rhsMyType = (MyType)rhs; // Should throw exception
    if(this.field1().equals(rhsMyType.field1())... // Or whatever
}
도움이 되었습니까?

해결책

일반적으로, 구현할 때 동등한 경우, 인수 클래스가 시전하기 전에 구현 클래스와 동일하거나 호환되는지 여부를 확인할 수 있습니다. 이 같은:

if (getClass() != obj.getClass())
    return false;
MyObj myObj = (MyObj) obj;

이렇게하면 FindBugs 경고가 방지됩니다.

의견을 다루기위한 부수적 노트 :
어떤 사람들은 사용한다고 주장합니다 instanceof 대신에 getClass 유형 안전을 확인합니다. 그것에 대한 큰 논쟁이 있습니다. 나는 당신이 수업 평등을 확인할 수 있다고 언급했을 때 얻지 못했습니다. 또는 호환성이지만 탈출 할 수 없다고 생각합니다. 당신이 사용하는 경우 이것으로 요약됩니다 instanceof 클래스의 인스턴스와 서브 클래스 사례 간의 평등을 지원할 수 있지만 대칭 계약을 위반할 위험이 있습니다. equals. 일반적으로 사용하지 않는 것이 좋습니다 instanceof 당신이 그것을 필요로하고 당신이 무엇을하고 있는지 알고 있지 않는 한. 자세한 내용은 다음을 참조하십시오.

다른 팁

아마도 다음과 같은 일을 하고 있을 것입니다.

public class Foo {
  // some code

  public void equals(Object o) {
    Foo other = (Foo) o;
    // the real equals code
  }
}

이 예에서는 equals()의 인수에 대해 다음과 같이 가정합니다.Foo 유형이라고 가정합니다.그럴 필요는 없습니다!문자열을 얻을 수도 있습니다(이 경우 거의 확실히 false를 반환해야 합니다).

따라서 코드는 다음과 같아야 합니다.

public void equals(Object o) {
  if (!(o instanceof Foo)) {
    return false;
  }
  Foo other = (Foo) o;
  // the real equals code
}

(또는 더 엄격한 getClass() != o.getClass() Dave L.이 언급한

다음과 같이 볼 수도 있습니다.

Integer i = new Integer(42);
String s = "fourtytwo";
boolean b = i.equals(s);

이 코드에서 오류가 발생해야 하는 이유가 있나요? ClassCastException 정상적으로 끝내고 설정하는 대신 b 에게 false?

던지기 ClassCastException 에 대한 응답으로 .equals() 현명하지 않을 것입니다.비록 그것이 어리석은 질문일지라도("물론 문자열은 Foo와 같지 않습니다!") 그것은 여전히 ​​완벽하게 훌륭한 대답("아니오" ==)을 가진 유효한 질문이기 때문입니다. false).

WindBugs 경고를 무시하는 것이 좋습니다. 실제로, 평등이 예상치 못한 클래스의 객체로 호출되면, 그것은 거의 확실히 버그이며 버그에서 빨리 실패하고 싶습니다.

예를 들어 'ArrayList Files'가 있고 Call Files.crantains ( "MyFile.txt")가있는 경우 ClassCastException이 있으면 좋을 것입니다. 대신, Java는 거짓을 반환하며 해당 버그를 발견 할 때까지 오랜 시간이 걸릴 수 있습니다.

나는 다음과 같은 평등 (객체) 구현을 시작합니다.

if ((object == null) || !(object instaceof ThisClass)) {
    return false;
}

이것은 또한 FindBugs 경고를 방지하지만 자동으로 반환되지 않습니다. false 이 클래스의 서브 클래스가 전달 될 때 특히 동일하게 간주 될 수도 있습니다. equals(Object) 메소드가 무시되지 않았습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top