Closed Limgayoung closed 2 months ago
Q1.
63페이지에 float과 double은 equals를 사용하지 않고 compare로 비교하는 것을 권장하고 있습니다. Float과 Double의 cmopare와 equals의 동작 방식의 차이를 설명해 주실 수 있나요?
A1.
// Float.equals
public boolean equals(Object obj) {
return (obj instanceof Float)
&& (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
// Float.compare
public static int compare(float f1, float f2) {
if (f1 < f2)
return -1; // Neither val is NaN, thisVal is smaller
if (f1 > f2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use floatToRawIntBits because of possibility of NaNs.
int thisBits = Float.floatToIntBits(f1);
int anotherBits = Float.floatToIntBits(f2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
equals
의 경우 Object
의 equals
를 override 하므로 obj
를 받아 먼저 Float
타입이 맞는지부터 검사를 수행합니다.
만약 Float
타입이 맞다면 floatToIntBits()
라는 메서드를 호출하는데 이때 입력으로 들어온 obj
변수가 Float
으로 명시적 형 변환이 일어납니다.
문제는 .equals
를 사용할 때 입력으로 넣은 매개변수가 float
과 같은 primitive type일 때 발생하는데 기본형이어도 강제적으로 Float
형으로 변환되므로 오토박싱이 수행된다고 할 수 있습니다.
이러한 이유로 오토박싱이 일어난다고 책에서 설명하고 있습니다.
compare
의 경우 조금 다른데 먼저 입력 매개변수로 float
라는 기본 타입을 사용하는 것을 확인할 수 있습니다. 이는 compare
가 Float
타입의 value
값, 즉 기본 타입 값을 확인하기 때문입니다. 따라서 기본형으로만 비교가 진행되며 위의 코드상에서도 Float 타입으로의 형 변환 또는 오토박싱이 일어나지 않는 것을 확인할 수 있습니다.
따라서 많은 Float
타입을 비교/검사해야 하는 일이 발생할 경우, 오토 박싱이 일어나는 equals
보단 compare
를 사용하라고 이야기 하고 있습니다.
Q2.
또, Float과 Double의 equals는 오토박싱을 수반할 수 있으니 성능상 좋지 않다고 나와 있는데, 다른 기본타입들은 equals를 사용해도 오토박싱을 수반하지 않는지 궁금합니다.
A2.
결론부터 말씀드리자면 오토박싱이 수반됩니다. 아래는 Integer
타입의 equals
코드와 compare
코드입니다.
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
equals
코드를 보면 명시적으로 Integer
타입의 형 변환을 선언하고 있습니다. 따라서 만약 equals
의 입력 매개변수에 기본 타입이 들어온다면 오토박싱이 수반된다고 할 수 있습니다.equals
가 Object
의 메서드이기 때문에 입력 매개변수로 obj를 받는 것이 문제인 것으로 생각됩니다. obj 자체는 다형성에 의해 Integer
또는 기본형이 들어갈 수 있으나, obj
가 가진 값 intValue
를 가져오기 위해서는 해당 타입으로의 형 변환이 반드시 필요하기 때문입니다.2번에서 그렇다면 Integer 타입의 equals도 강제 형변환을 시키기 때문에 오토박싱이 일어나는 것은 같을 것 같습니다. 다른 기본형들도 compare를 사용하는 것이 성능상 좋을 것 같은데 왜 Float과 Double만 특별히 compare를 사용하는 것을 권장하는 것인지 알 수 있을까요?
다른 기본형들은 ==
이라는 좋은 연산자를 제공합니다. float, double의 경우 실수 타입으로 인한 정밀도 차이로 인해 ==
의 사용이 권장되지 않아 특별하게 compare를 사용하는 것으로 생각됩니다.
아하!! 제가 책이 없을 때 추가 질문을 해서 책에서 기본형은 equals를 권하는 것으로 착각했네요! 감사합니다 ~ ㅎㅎ
63페이지에 float과 double은 equals를 사용하지 않고 compare로 비교하는 것을 권장하고 있습니다. Float과 Double의 cmopare와 equals의 동작 방식의 차이를 설명해 주실 수 있나요?
또, Float과 Double의 equals는 오토박싱을 수반할 수 있으니 성능상 좋지 않다고 나와 있는데, 다른 기본타입들은 equals를 사용해도 오토박싱을 수반하지 않는지 궁금합니다.