문제

게 찾을 수 있는 방법은 무엇인가 발생 equals()to return false?

나는지에 대해 묻는 확실한 방법은 항상 올바른 접근 방식이지만,무언가의 개발을 돕는 과정이다.현재 갖고 있는 단계로 equals()통화(일반적으로 나무들)까지 하나 그들은 거짓,그 다음 단계로 it,광고 싫증을.

나는 생각에 대한 개체를 사용하여 그래프를 출력 xml 와 비교합니다.그러나,XMLEncoder 필요한 기본 생성자,jibx 필요로 미리 컴파일,x-stream 고 간단한 api 에서 사용되지 않습니다.지 않아요 마음이 복사하는 하나의 클래스,또는 패키지로 시험 지역을 사용하여 그것이있다,그러나 가져오는 전체 항아리에 대한 이 그냥 일어나기 위하여 려고 하고 있지 않다.

또한 생각 구축에 대한 개체 그래프 크로스 자가 아직도 그것은,그러나 내가 싫어하는 시작을 다루는 특별한 경우(주문 컬렉션,비 주문 컬렉션,지도...)

어떤 아이디어에 대해 이동하는 방법은?

편집:알 추가 단지의 일반적인 방법으로 일 것입니다.난 단지는 재사용할 수 있는 단위입니다.그러나 필요한 관료(내에서 프로젝트)이를 위해 정당화하지 않은 결과-나에 디버깅 및 스테핑입니다.

도움이 되었습니까?

해결책

아마도 전체 그래프 비교가 아닐 것입니다 ... 당신의 평등이 각 클래스의 모든 속성을 포함하지 않는 한 ... (당신은 시도 할 수 있습니다 == :)).

노력하다 Hamcrest 매칭 - "모든"매치 자에서 각 매칭자를 작성할 수 있습니다.

Matcher<MyClass> matcher = CoreMatchers.allOf(
  HasPropertyWithValue.hasProperty("myField1", getMyField1()),
  HasPropertyWithValue.hasProperty("myField2", getMyField2()));
if (!matcher.matches(obj)){
  System.out.println(matcher.describeFailure(obj));
  return false;
}
return true;

'Myfield1은 "가치"의 가치를 가질 것으로 예상하지만 "다른 가치"라고 예상 할 것입니다.

물론 정적 공장을 인화 할 수 있습니다. 이것은 사용하는 것보다 조금 무겁습니다 Apache-Commons EqualsBuilder, 그러나 그것은 당신에게 정확히 실패한 것에 대한 정확한 설명을 제공합니다.

이러한 표현식을 신속하게 만들기 위해 자신만의 특수 매칭을 만들 수 있습니다. 복사하는 것이 현명 할 것입니다 Apache-Commons EqualsBuilder 여기.

BTW, Hamcrest Basic Jar는 32K (소스 포함!)는 코드를 검토하고 상사에게 "내 자신의 코드로서 이것에 대해 서있을 것"이라고 말할 수있는 옵션을 제공합니다.

다른 팁

객체 그래프의 클래스에서 "동일"을 패치하기 위해 측면을 사용하여 객체 상태를 False를 반환 할 때 파일에 로그인하게 만들 수 있습니다. 물체 상태를 기록하려면 Beanutils와 같은 것을 사용하여 물체를 검사하고 버릴 수 있습니다. 이것은 작업 공간에서 쉽게 사용할 수있는 JAR 기반 솔루션 중 하나입니다.

트리에 저장된 객체의 계층 구조가 충분히 간단한 경우, "동일"이 거짓을 반환 할 때만 트리거되는 클래스 "동일"구현에 조건부 중단 점을 배치 할 수 있습니다. 디버거 액세스가있는 곳마다 이것을 사용할 수 있습니다. 일식은 이것을 잘 처리합니다.

당신이 원하는 것 같습니다 자바-디프, 또는 그와 비슷한 것.

좋아, 이것은 완전히 기괴한 방법이지만 새로운 정적 방법을 소개하는 것은 어떻습니까?

public static boolean breakableEquals(Object o1, Object o2)
{
    if (o1 == o2)
    {
        return true;
    }
    if (o1 == null || o2 == null)
    {
        return false;
    }
    // Don't condense this code!
    if (o1.equals(o2))
    {
        return true;
    }
    else
    {
        return false;
    }
}

나는 마지막 비트가 화를내는 것처럼 보이지만 차이점은 "반환 거짓"에 중단 점을 넣을 수 있다는 것입니다. 당신이 사용하는 경우 breakableEquals 당신의 모든 깊은 평등 비교에서, 당신은 당신이 첫 번째를 때리 자마자 깨질 수 있습니다. "return false".

원시적 값을 많이 비교하는 경우에는 큰 도움이되지 않지만 도움이 될 수 있습니다. 나는 실제로 이것을 사용한 적이 있다고 말할 수는 없지만 왜 그것이 작동하지 않는지 알 수 없습니다. 물론 조금 덜 효율적일 것입니다. 따라서 고성능 코드를 다루는 경우 나중에 변경할 수 있습니다.

또 다른 옵션은 다음과 같은 것을 사용하는 것입니다.

boolean result = // comparison;
return result;

IDE가 지원한다고 가정하면 Return 문에 조건부 중단 점을 놓고 조건을 설정할 수 있습니다. "!result".

또 다른 옵션 :

public static boolean noOp(boolean result)
{
    return result;
}

그런 다음 비교 내에서 이것을 사용할 수 있습니다.

return Helpers.noOp(x.id == y.id) &&
       Helpers.noOp(x.age == y.age);

디버깅하지 않으면 JIT에 의해 최적화되기를 바랍니다. 그러나 다시 조건부 중단 점을 사용할 수 있습니다. noOp. 불행히도 코드를 추악하게 만듭니다.

간단히 말해서 : 여기서는 특별히 매력적인 솔루션이 아니라 몇 가지 아이디어 ~할 것 같다 특정 상황에서 도움.

나는 단일 클래스 나 패키지를 내 테스트 영역에 복사하여 거기에 사용하는 것을 신경 쓰지 않지만,이를 위해 전체 항아리를 가져 오는 것은 일어나지 않을 것입니다.

음 ... 뭐? ClassPath에 항아리를 추가하는 것은 클래스 복사 클래스 또는 소스 코드로 전체 패키지보다 프로젝트에 더 쉽고 방해가되지 않습니다.

특정 문제에 관해서는, 평등을 결정하기 위해 많은 다른 속성을 사용하는 다양한 클래스가 있습니까? 후자의 경우, "return false"문에 중단 점을 넣을 수 있도록 equals () 메소드를 strucutre하는 것은 매우 쉽습니다. 전자의 경우, 이것은 너무 많은 일일 수 있다고 생각합니다. 그러나 XML 기반 비교는 의미 적으로 동일한 객체 (예 : 세트와 맵)의 차이를 보여주기 때문에 작동하지 않을 수 있습니다.

프로젝트가 JAR을 추가 할 수 없다는 점을 감안할 때 다른 프로젝트가 달성하기 위해 상당한 양의 코드를 취하는 솔루션을 전체적으로 구현하는 것은 대답을 넘어서는 것 같습니다 (그리고 JAR에 잘 포함).

디버거의 조건부 중단 점 - 비 코드 솔루션은 어떻습니까? 메소드가 False를 반환하는 경우에만 해당 트립을 추가하고 모든 관련 클래스에 넣을 수 있습니다. 스테핑 없음.

항아리를 추가하는 것이 정상적인 일을하는 방법이라는 것을 알고 있습니다. 항아리가 재사용 가능한 유닛이라는 것을 알고 있습니다. 그러나이를 위해 필요한 관료주의는 결과를 정당화하지 않습니다. 나는 계속해서 디버깅하고 들어 섰습니다.

이 주위의 한 가지 방법은 스프링과 같은 도서관 (다른 항아리를 뽑는 것)을 포함하는 것입니다. 스프링 프로젝트를 실제로 사용하지 않은 스프링 프로젝트를 보았으므로 묶인 항아리를 사용할 수 있습니다.

Commons-JXPATH 물체 트리를 신속하게 검사하는 데 유용 할 수 있습니다. 나는 항아리를 포함하는 문제를 완전히 이해하지 못하지만 디버깅 중에 표현식을 사용할 수있는 IDE에서 자신의 프로젝트에서 사용할 수 있습니다.

아마도 이거 기사 방법 추적에 대해 도움이 될 것입니다.

작동 방식

사용자 정의 클래스 로더는 클래스 파일을 읽고 추적 코드를 사용하여 각 방법을 읽습니다. 클래스 로더는 또한 각 클래스에 정적 필드를 추가합니다. 이 필드에는 'ON'과 'OFF'의 두 상태가 있습니다. 추적 코드는 인쇄하기 전에이 필드를 확인합니다. 명령 줄 옵션은이 정적 필드에 액세스하고 수정하여 추적 출력을 제어합니다.

그들이 보여주는 샘플 출력은 일부 방법의 반환 값 (Isapplet과 같은)을 보여 주므로 문제에 대해 유망한 것처럼 보입니다.

isapplet = false

Equals에서 False를 반환하기 시작한 정확한 클래스를 발견하는 것은 쉽습니다. 페이지의 전체 샘플 출력은 다음과 같습니다.


| Swingset2. ()
| Swingset2.
| Swingset2.main ([ljava.lang.string;@1dd95c)
|| isapplet (swingset2@3d12a6)
|| isapplet = false
|| swingset2.createframe (apple.awt.cgraphicsconfig@93537d)
|| wingset2.createframe=javax.swing.jframe@cb01e3
|| CreatesPlashscreen (Swingset2@3d12a6)
||| createImageicon (swingset2@3d12a6, "splash.jpg", "splash.accessible_description")
||| createimageicon=javax.swing.imageicon@393e97
||| isapplet (swingset2@3d12a6)
||| isapplet = false
||| getframe (swingset2@3d12a6)
||| getframe=javax.swing.jframe@cb01e3
||| getframe (swingset2@3d12a6)
||| getframe=javax.swing.jframe@cb01e3
|| CreatesPlashscreen
.Run (Swingset2 $ 1@fba2af)
..Showsplashscreen (Swingset2@3d12a6)
... IsApplet (Swingset2@3d12a6)
... isapplet = false
.. ShowsPlashscreen
.운영
|| 초기화 된 이모 (swingset2@3d12a6)
||| Createmenus (Swingset2@3d12a6)
|||| getString (Swingset2@3d12a6, "menubar.accessible_description")
||||| getResourceBundle (Swingset2@3d12a6)
||||| getResourceBundle=java.util.propertyresourcebundle@6989e
|||| getstring = "스윙 데모 메뉴 바"

XMLEncoder 만 인코딩합 콩 속성하는 반면,같음 할 수 있는 물론,작업에 비 콩고 어떤 내부 필드가 있습니다.

문제의 일부는 당신이 알고하지 않 같은 실제적으로 찾고 있습니다.체할 수 있는 많은 다른 분야 아직도 그것을 주장과 같았을 다른 개체,그것은 있을 수도 있는 다른 유형입니다.(예를 들어,사용자 정의 URL 을 클래스의 반환할 수 있습니다 진정한 문자열에 해당하는 그것의 외부 양식).

그래서 나는 생각하지 않는다 바이트코드 계측 할 수 있는 실제로 수정 클래스 equals()함수에 무엇을 볼 필드 그것을 액세스합니다.그럼에도,그것은 여전히 수 extreemly 하기 어려운'진실로'왜 기능을 반환되는 거짓입니다.하지만 희망이 될 것이라는 간단한 문제의 비교하는 필드를 실제로에서 액세스 equals()

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