이전에 포스팅을 진행하며 동일성과 동등성에 관하여 언급한 기억이 있는데 다시 상기시킬겸 좀더 상세히 작성하려고 포스팅을 진행한다.
동일성과 동등성의 사전적의미는 다음과 같다.
동일성 (identity) - 객체가 완전히 같은경우를 의미한다
동등성 (equality) - 값이 같은경우를 의미한다.
한가지 예시를 들어보겠다.
위의 사진처럼 똑같은 모델, 똑같은 스펙의 핸드폰이 있다. (좌측을 A, 우측을 B라 가정)
그렇다면 이것을 동일하다고 설명할 수 있을까?
A와 B는 스펙은 똑같을지언정 제품마다 별도의 제조번호가 부여되었고 이는 2개의 핸드폰이 엄연히 다르다는것을 보여주는것으로 즉, A와 B는 동등(equality)하지만 동일(identity)하지는 않다고 말하는것이다.
이러한 동등성과 동일성을 자바에서는 hashcode 메서드와 equal 메서드로 확인할수 있다.
동등성 - equal()
public boolean equals (Object anObject){
if (this == anObject){
return true;
}
if (anObject intstanceof String)
String aString = (String)anObject;
if(coder() == aString.coder()) {
return isLatin1() ? StringLatin1.equals(value,aString.value)
:StringUTF16.equals(value, aString.value);
}
}
return false;
}
상단의 코드는 Object의 내장함수중 equals의 로직을 보여주는 코드로 객체의 값이 일치하는 여부(boolean)를 반환하는 메서드이다 ("=="을 의미한다)
메모리 주소가 아닌 객체 값만을 비교하는 메서드이다.
3항 연산자를 사용해 StingLatin1과 StringUTF16를 비교하여 반환하기로 하는 메서드이다.
StringUTF16 = JVM이 문자, 문자열을 메모리에 저장할때 UTF16을 사용하여 인코딩 하는데 이를 같은지를 확인하기 위해 StringUTF16.equal()메서드를 사용하였다.
isLatin1
private boolean isLatin1() {
return COMPACT_STRINGS && coder == LATIN1;
}
coder() =
byte 배열(value)을 인코딩하는데 사용하는 변수이며 그리고 지원하는 인코딩 타입은 LATIN1, UTF16 이다.
/**
* The identifier of the encoding used to encode the bytes in
* {@code value}. The supported values in this implementation are
*
* LATIN1
* UTF16
*
* @implNote This field is trusted by the VM, and is a subject to
* constant folding if String instance is constant. Overwriting this
* field after construction will cause problems.
*/
private final byte coder;
equals 연산자는 두객체의 동등성을 판별하기 위하여 사용하지만 equals연산자를재정의하지 않으면 내부적으로 == 연산자와 같은 로직을 수행하므로 차이가 없다 그렇기때문에 각 객체의 특성에 맞게 재정의를 하여야 동등성의 기능을 수행한다.
//int형 equals 연산자
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
//Object의 equals 연산자
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
//ArrayList의 equals 연산자
private boolean equalsArrayList(ArrayList<?> other) {
final int otherModCount = other.modCount;
final int s = size;
boolean equal;
if (equal = (s == other.size)) {
final Object[] otherEs = other.elementData;
final Object[] es = elementData;
if (s > es.length || s > otherEs.length) {
throw new ConcurrentModificationException();
}
for (int i = 0; i < s; i++) {
if (!Objects.equals(es[i], otherEs[i])) {
equal = false;
break;
}
}
}
other.checkForComodification(otherModCount);
return equal;
}
동일성 - hashcode()
hashcode란 객체를 식별할 하나의 정수값을 의미한다. 일반적으로 객체의 주소값(메모리번지)을 변환하여 생성한 객체의 고유한 정수값이다.
(논리적 동등 비교시 hashcode를 오버라이딩 할 필요성이 있다고 하는데 이것은 hashset,hashmap,hashtable방식이며 3항목은 강의 순서에 맞게 나중에 돌아와서 추가로 작성예정..)
public class Key{
public int number;
public Key(int number){
this.number = number;
}
@Override
public boolean equals(Object obj) [
if(obj instanceof Key) { //클래스확인용
Key compareKey = (key) obj; //캐스팅
if(this.number == compareKey.number) {
return ture;
}
}
return false;
}
}
//instanceof는 서로 알맞는 타입을 찾을때까지 컴파일시 모든 타입을 돌며 검사하는데 이러한 단점때문에 가급적 다형성을 활용한 타입점검이 필요하다