자바 향상 편(12)---equals()

6327 단어 equals()
equals()
초 클래스 Object 에는 이 equals()방법 이 있 는데 이 방법 은 주로 두 대상 이 같 는 지 비교 하 는 데 사용 된다.이 방법의 원본 코드 는 다음 과 같다.
public boolean equals(Object obj) {
    return (this == obj);
    }

우 리 는 모든 대상 이 표지(메모리 주소)와 상태(데이터)를 가지 고 있다 는 것 을 알 고 있 으 며,동시에'=='은 두 대상 의 메모리 주 소 를 비교 하 는 것 입 니 다.따라서 Object 를 사용 하 는 equals()방법 은 두 대상 의 메모리 주소 가 같 는 지 비교 하 는 것 입 니 다.즉,object 1.equals(object 2)가 true 라면 equals 1 과 equals 2 는 실제 적 으로 같은 대상 을 참조 하 는 것 입 니 다.가끔 은 Object 의 equals()방법 이 우리 의 기본 적 인 요 구 를 만족 시 킬 수 있 지만 우 리 는 우리 가 많은 시간 을 두 대상 의 비 교 를 해 야 한 다 는 것 을 알 아야 한다.이 럴 때 Object 의 equals()방법 은 안 된다.실제로 JDk 에서 String,Math 등 패 키 징 류 는 equals()방법 에 대해 다시 썼 다.다음은 String 의 equals()방법 입 니 다.
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
    }

이 코드 세그먼트:if(v1[i++]!=v2[j++])return false;우 리 는 String 의 equals()방법 이 인용 비교 가 아니 라 내용 비 교 를 하 는 것 임 을 분명하게 볼 수 있다.다른 포장 류 는 많 지 않다.
자바 규범 에서 equals()방법 에 대한 사용 은 다음 과 같은 몇 가지 규칙 을 따라 야 합 니 다.
equals 방법 은 비 어 있 는 대상 참조 에서 같은 관 계 를 실현 합 니 다.
1.자 반 성:비 공 인용 치 x,x.equals(x)는 true 로 돌아 가 야 합 니 다.
2.대칭 성:모든 비 공 인용 값 x 와 y 에 대해 y.equals(x)가 true 로 돌아 갈 때 x.equals(y)는 true 로 돌아 가 야 합 니 다.
3.전달 성:비어 있 지 않 은 인용 값 x,y,z 에 대해 x.equals(y)가 true 로 돌아 가 고 y.equals(z)가 true 로 돌아 가면 x.equals(z)는 true 로 돌아 가 야 합 니 다.
4.일치 성:빈 인용 값 x 와 y 에 대해 x.equals(y)를 여러 번 호출 하여 true 로 되 돌아 가 거나 false 로 되 돌아 갑 니 다.전 제 는 대상 의 equals 비교 에 사용 되 는 정보 가 수정 되 지 않 았 다 는 것 입 니 다.
5.비 어 있 는 참조 값 x,x.equals(null)는 false 로 돌아 가 야 합 니 다.
위의 몇 가지 규칙 에 대해 우 리 는 사용 하 는 과정 에서 지 키 는 것 이 가장 좋다.그렇지 않 으 면 예상 치 못 한 오류 가 발생 할 것 이다.
자바 에서 비교 하려 면 비교 유형 에 따라 적당 한 비교 방식 을 선택해 야 합 니 다.
1)대상 도 메 인,equals 방법 을 사용 합 니 다.2)유형 안전 매 거 진,equals 또는=을 사용 합 니 다.3)null 의 대상 필드 일 수 있 습 니 다:사용==equals.4)배열 필드:Arrays.equals 를 사용 합 니 다.5)float 와 double 을 제외 한 원시 데이터 형식:사용==.6)float 형식:Float.foatToIntBits 를 사용 하여 int 형식 으로 변환 한 다음==을 사용 합 니 다.7)double 타 입:Double.double ToLongBit 를 사용 하여 long 타 입 으로 변환 한 후 사용==.
6),7)왜 전환 이 필요 한 지 에 대해 우 리 는 그들 이 해당 하 는 패키지 류 의 equals()방법 을 참고 할 수 있 습 니 다.다음은 Float 류 입 니 다.
public boolean equals(Object obj) {
    return (obj instanceof Float)
           && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
    }

그 이 유 는 두 가지 가 언급 되 어 있 습 니 다.
However, there are two exceptions:
If f1 and f2 both represent
Float.NaN, then the equals method returns
true, even though Float.NaN==Float.NaN
has the value false.
If <code>f1 represents +0.0f while
f2 represents -0.0f, or vice
versa, the equal test has the value
false, even though 0.0f==-0.0f
has the value true.

equals()에서 getClass 를 사용 하여 유형 판단
저 희 는 equals()방법 을 복사 할 때 보통 getClass 를 사용 하여 유형 판단 을 하 는 것 을 추천 합 니 다.instanceof 를 사용 하 는 것 이 아 닙 니 다.인 스 턴 스 of 의 역할 은 왼쪽 대상 이 오른쪽 클래스 의 인 스 턴 스 인지 판단 하고 boolean 형식의 데 이 터 를 되 돌려 주 는 것 임 을 잘 알 고 있 습 니 다.계승 중인 하위 클래스 의 인 스 턴 스 가 부모 클래스 의 실현 여 부 를 판단 할 수 있 습 니 다.뒤에 있 는 이 말 을 주의 하 세 요.계승 중인 하위 클래스 의 인 스 턴 스 가 아버지 류 의 실현 인지 아 닌 지 를 판단 할 수 있 습 니 다.바로 이 말 이 이상 한 짓 을 하고 있 습 니 다.우 리 는 먼저 다음 과 같은 실례 를 본다.
부류:Person
public class Person {
    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public Person(String name){
        this.name = name;
    }
    
    public boolean equals(Object object){
        if(object instanceof Person){
            Person p = (Person) object;
            if(p.getName() == null || name == null){
                return false;
            }
            else{
                return name.equalsIgnoreCase(p.getName());
            }
        }
        return false;
    }
}

하위 클래스:Employee
public class Employee extends Person{
    private int id;
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Employee(String name,int id){
        super(name);
        this.id = id;
    }
    
    /**
     *   equals()  
     */
    public boolean equals(Object object){
        if(object instanceof Employee){
            Employee e = (Employee) object;
            return super.equals(object) && e.getId() == id;
        }
        return false;
    }
}

위의 부모 클래스 Person 과 하위 클래스 Employee 는 equals()를 다시 썼 지만 Employee 는 부모 클래스 보다 id 속성 이 하나 더 많 습 니 다.테스트 프로그램 은 다음 과 같 습 니 다.
public class Test {
    public static void main(String[] args) {
        Employee e1 = new Employee("chenssy", 23);
        Employee e2 = new Employee("chenssy", 24);
        Person p1 = new Person("chenssy");
        
        System.out.println(p1.equals(e1));
        System.out.println(p1.equals(e2));
        System.out.println(e1.equals(e2));
    }
}

위 에서 두 명의 직원 과 한 명의 일반인 을 정의 했다.비록 그들 은 동명 이인 이지 만 그들 은 틀림없이 같은 사람 이 아니 기 때문에 이치 대로 말 하면 출력 결 과 는 모두 false 여야 하지만 뜻 대로 되 지 않 았 다.결 과 는 true,true,false 이다.
그 e1 에 대해!=e2 우 리 는 쉽게 이해 할 수 있 습 니 다.왜냐하면 그들 은 name 뿐만 아니 라 id 도 비교 해 야 하기 때 문 입 니 다.그러나 p1 은 e1 과 같 고 e2 와 같 습 니 다.이것 은 매우 이상 한 것 입 니 다.e1,e2 는 분명히 두 개의 다른 유형 이지 만 왜 이런 상황 이 발생 했 습 니까?우선 p1.equals(e1)는 p1 을 호출 하 는 equals 방법 입 니 다.이 방법 은 instanceof 키 워드 를 사용 하여 e1 이 Person 류 인지 확인 합 니 다.여기 서 instanceof 를 살 펴 보 겠 습 니 다.왼쪽 대상 이 오른쪽 클래스 의 인 스 턴 스 인지 판단 하고 계승 중인 하위 클래스 의 실제 사례 가 부모 클래스 의 실현 인지 판단 할 수 있 습 니 다.그들 둘 은 상속 관계 가 존재 하기 때문에 틀림없이 true 로 돌아 갈 것 이다.그러나 둘 의 name 은 같 기 때문에 결 과 는 틀림없이 true 일 것 이다.
그래서 위의 상황 이 바로 키워드 인 instanceof 를 사 용 했 는데 이것 은 매우 쉬 운'전문 적 인 빈틈'이다.따라서 equals 를 복사 할 때 getClass 를 사용 하여 유형 판단 을 하 는 것 을 추천 합 니 다.인 스 턴 트 오 브 를 사용 하 는 것 이 아니 라
기 초 를 공 고 히 하고 기술 을 향상 시 키 며 어려움 을 두려워 하지 않 고 고봉 등반!!!!!!

좋은 웹페이지 즐겨찾기