-
์์ดํ 10. equals๋ ์ผ๋ฐ ๊ท์ฝ์ ์ง์ผ ์ฌ์ ์ํ๋ผDevBook/Effective Java 2023. 5. 6. 22:53
๐์ํฉ
- Object ํด๋์ค์ equals() ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํด์ผ ํ๋ ๊ฒฝ์ฐ๋ ๋ฌด์์ผ๊น?
- ์ค๋ฒ๋ผ์ด๋ฉ์ ํ ๋ ์ง์ผ์ผ ํ ์ผ๋ฐ ๊ท์ฝ์ ๋ฌด์์ผ๊น?
๐๋ฐฉ๋ฒ
โถ๏ธ equals๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ์ง ์์๋ ๋๋ ๊ฒฝ์ฐ
- ์ค๋ฒ๋ผ์ด๋ฉํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ์ผ๋ก ๊ทธ ํด๋์ค์ ์ธ์คํด์ค๋ ์ค์ง ์๊ธฐ ์์ ๊ณผ๋ง ๊ฐ๊ฒ ๋จ
- ๋ค์์์ ์ด๊ฑฐํ ์ํฉ ์ค ํ๋์ ํด๋นํ๋ค๋ฉด ์ฌ์ ์ํ์ง ์๋ ๊ฒ์ด ์ต์ ์
1. ๊ฐ ์ธ์คํด์ค๊ฐ ๋ณธ์ง์ ์ผ๋ก ๊ณ ์ ํจ
- ๊ฐ์ ํํํ๋๊ฒ ์๋๋ผ ๋์ํ๋ ๊ฐ์ฒด๋ฅผ ํํํ๋ ํด๋์ค๊ฐ ์ฌ๊ธฐ ํด๋นํจ
- ex) Thread --> Object์ equals ๋ฉ์๋๋ ์ด๋ฌํ ํด๋์ค์ ๋ฑ ๋ง๊ฒ ๊ตฌํ๋์์
2. ์ธ์คํด์ค์ '๋ ผ๋ฆฌ์ ๋์น์ฑ(logical equality)'์ ๊ฒ์ฌํ ์ผ์ด ์์
- ์ธ์คํด์ค์ ๋ด๋ถ ๊ฐ์ด ๋์ผํ์ง ๊ฒ์ฌํ์ง ์์๋ ๋จ
3. ์์ ํด๋์ค์์ ์ฌ์ ์ํ equals๊ฐ ํ์ ํด๋์ค์๋ ๋ค์ด๋ง์
- Set ๊ตฌํ์ฒด๋ AbstractSet์ด ๊ตฌํํ equals๋ฅผ ์์๋ฐ์ ์ฐ๊ณ , List๋ Map ๊ตฌํ์ฒด๋ ๋ง์ฐฌ๊ฐ์ง์
4. ํด๋์ค๊ฐ private์ด๊ฑฐ๋ package-private์ด๊ณ equals ๋ฉ์๋๋ฅผ ํธ์ถํ ์ผ์ด ์์
โถ๏ธ equals๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ ํด์ผ๋๋ ๊ฒฝ์ฐ
์ธ์คํด์ค์ '๋ ผ๋ฆฌ์ ๋์น์ฑ'์ ํ์ธํด์ผ ํ ๋
- ๊ฐ์ฒด ์๋ณ์ฑ(object identity : ๋ ๊ฐ์ฒด๊ฐ ๋ฌผ๋ฆฌ์ ์ผ๋ก ๊ฐ์๊ฐ)์ด ์๋๋ผ ๋ ผ๋ฆฌ์ ๋์น์ฑ์ ํ์ธํด์ผ ํ๋๋ฐ, ์์ ํด๋์ค์ equals๊ฐ ๋ ผ๋ฆฌ์ ๋์น์ฑ์ ๋น๊ตํ๋๋ก ์ฌ์ ์๋์ง ์์์ ๋๋ฅผ ์๋ฏธํจ
- ์ฃผ๋ก ๊ฐ ํด๋์ค๋ค์ด ์ฌ๊ธฐ์ ํด๋นํจ
- ๊ฐ ํด๋์ค๋?
- Integer์ String์ฒ๋ผ ๊ฐ์ ํํํ๋ ํด๋์ค
- ๋ ๊ฐ ๊ฐ์ฒด๋ฅผ equals๋ก ๋น๊ตํ๋ ๊ฒฝ์ฐ ๊ฐ์ฒด๊ฐ ๊ฐ์์ง๊ฐ ์๋๋ผ ๊ฐ์ด ๊ฐ์์ง๋ฅผ ์๊ณ ์ถ์
- equals๊ฐ ๋ ผ๋ฆฌ์ ๋์น์ฑ์ ํ์ธํ๋๋ก ์ฌ์ ์ํ์ฌ ์ด๋ฅผ ๊ตฌํํ๊ณ , Map์ ํค์ Set์ ์์๋ก ์ฌ์ฉํ ์ ์๊ฒ ๋จ (์ค๋ณต๋์ง ์์์ผ ํ๋ ๊ฒ๋ค)
- ์์ธ๋?
- ๊ฐ ํด๋์ค์ฌ๋, ๊ฐ์ด ๊ฐ์ ์ธ์คํด์ค๊ฐ ๋ ์ด์ ๋ง๋ค์ด์ง์ง ์์์ ๋ณด์ฅํ๋ ์ธ์คํด์ค ํต์ ํด๋์ค๋ผ๋ฉด equals๋ฅผ ์ฌ์ ์ํ์ง ์์๋ ๋จ (Enum ํด๋์ค๋ ์ฌ๊ธฐ์ ํด๋น)
- ์ด์ฐจํผ ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ฐ์ ์ธ์คํด์ค๊ฐ 2๊ฐ ์ด์ ๋ง๋ค์ด์ง์ง ์์ผ๋ฏ๋ก ๋ ผ๋ฆฌ์ ๋์น์ฑ๊ณผ ๊ฐ์ฒด ์๋ณ์ฑ์ด ์ฌ์ค์ ๋๊ฐ์ ์๋ฏธ๊ฐ ๋จ
- ๊ฐ ํด๋์ค๋?
โถ๏ธ ์ค๋ฒ๋ผ์ด๋ฉ ์ ๋ฐ๋์ ๋ฐ๋ผ์ผ ํ๋ ์ผ๋ฐ ๊ท์ฝ
- ๊ท์ฝ์ ๋ฐ๋ผ์ผ ํ๋ ์ด์ ?
- ํ ํด๋์ค์ ์ธ์คํด์ค๋ ๋ค๋ฅธ ๊ณณ์ผ๋ก ๋น๋ฒํ ์ ๋ฌ๋์ด ์ฌ์ฉ๋จ
- ์ด๋ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๋ ์ชฝ์์๋ ์ ๋ฌ๋ฐ์ ๊ฐ์ฒด๊ฐ equals ๊ท์ฝ์ ์งํจ๋ค๊ณ ๊ฐ์ ํ๊ณ ๋์ํจ
- ๋ค์์ Object ๋ช ์ธ์ ์ ํ ๊ท์ฝ์
1. ๋ฐ์ฌ์ฑ
- ๊ฐ์ฒด๋ ์๊ธฐ ์์ ๊ณผ ๊ฐ์์ผ ํจ
2. ๋์นญ์ฑ
- ๋ ๊ฐ์ฒด๋ ์๋ก์ ๋ํ ๋์น ์ฌ๋ถ์ ๋๊ฐ์ด ๋ตํด์ผ ํจ
3. ์ถ์ด์ฑ
- ๊ทธ ์์ฒด๋ก ์ธ์คํด์ค ์์ฑ์ด ๊ฐ๋ฅํ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ํ์ฅํด ์๋ก์ด ๊ฐ์ ์ถ๊ฐํ๋ฉด์ equals ๊ท์ฝ์ ๋ง์กฑ์ํฌ ๋ฐฉ๋ฒ์ ์กด์ฌํ์ง ์์
- ์ถ์ ํด๋์ค์ ํ์ ํด๋์ค์์๋ผ๋ฉด equals ๊ท์ฝ์ ์งํค๋ฉด์ ๊ฐ ์ถ๊ฐ๊ฐ ๊ฐ๋ฅํจ (์์ ํด๋์ค๋ฅผ ์ง์ ์ธ์คํด์ค๋ก ๋ง๋๋ ๊ฒ ๋ถ๊ฐ๋ฅ ํ๋๊น)
- ์ฐํ ๋ฐฉ๋ฒ์ผ๋ก๋ '์์ ๋์ ์ปดํฌ์ง์
์ฌ์ฉ' ํ๋ ๋ฐฉ๋ฒ์ด ์์
- ex) Point๋ฅผ ์์ํ๋ ๋์ Point๋ฅผ ColorPoint์ private ํ๋๋ก ๋
์ฝ๋ 10-5 equals ๊ท์ฝ์ ์งํค๋ฉด์ ๊ฐ ์ถ๊ฐํ๊ธฐ
public class ColorPoint { private final Point point; private final Color color; public ColorPoint(int x, int y, Color color) { point = new Point(x, y); this.color = Objects.requireNonNull(color); } public Point asPoint() { return this.point; } @Override public boolean equals(Object o) { if (!(o instanceof ColorPoint)) return false; ColorPoint cp = (ColorPoint) o; return cp.point.equals(this.point) && cp.color.equals(this.color); } ... }
4. ์ผ๊ด์ฑ
- ๋ ๊ฐ์ฒด๊ฐ ๊ฐ๋ค๋ฉด ์์ผ๋ก๋ ์์ํ ๊ฐ์์ผ ํจ์ ์๋ฏธํจ (๋ถ๋ณ ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ)
5. null-์๋
- ๋ชจ๋ ๊ฐ์ฒด๊ฐ null๊ณผ ๊ฐ์ง ์์์ผ ํจ
//๋ช ์์ null ๊ฒ์ฌ - ํ์ ์๋ค! @Override public boolean equals(Object o) { if (o == null) return false; ... } //๋ฌต์์ null ๊ฒ์ฌ - ๊ถ์ฅ! @Override public boolean equals(Object o) { if (!(o instanceof MyType)) return false; MyType mt = (MyType) o; ... }
โถ๏ธ equals ๋ฉ์๋ ๊ตฌํ ๋ฐฉ๋ฒ ๋จ๊ณ๋ณ ์ ๋ฆฌ
1. == ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด ์ ๋ ฅ์ด ์๊ธฐ ์์ ์ ์ฐธ์กฐ์ธ์ง ํ์ธํจ
- ์๊ธฐ ์์ ์ด๋ฉด true๋ฅผ ๋ฐํํจ
- ์ด๋ ๋จ์ํ ์ฑ๋ฅ ์ต์ ํ์ฉ์ผ๋ก, ๋น๊ต ์์ ์ด ๋ณต์กํ ์ํฉ์ผ ๋ ์ ์ฉํจ
2. instanceof ์ฐ์ฐ์๋ก ์ ๋ ฅ์ด ์ฌ๋ฐ๋ฅธ ํ์ ์ธ์ง ํ์ธํจ
3. ์ ๋ ฅ์ ์ฌ๋ฐ๋ฅธ ํ์ ์ผ๋ก ํ๋ณํํจ
- 2์์ instanceof ๊ฒ์ฌ๋ฅผ ํ์ผ๋ฏ๋ก ์์ธ๊ฐ ๋ฐ์ํ์ง ์์
4. ์ ๋ ฅ ๊ฐ์ฒด์ ์๊ธฐ ์์ ์ ๋์๋๋ 'ํต์ฌ' ํ๋๋ค์ด ๋ชจ๋ ์ผ์นํ๋์ง ํ๋์ฉ ๊ฒ์ฌํจ
- ๋ชจ๋ ํ๋๊ฐ ์ผ์นํ๋ฉด true, ํ๋๋ผ๋ ๋ค๋ฅด๋ค๋ฉด false๋ฅผ ๋ฐํํจ
โถ๏ธ ํ๋ ๋น๊ต ๋ฐฉ์
- float์ double์ ์ ์ธํ ๊ธฐ๋ณธ ํ์ ํ๋๋ == ์ฐ์ฐ์๋ก ๋น๊ต
- ์ฐธ์กฐ ํ์ ํ๋๋ equals ๋ฉ์๋๋ก ๋น๊ต
- float์ double์ ๊ฐ๊ฐ ์ ์ ๋ฉ์๋์ธ Float.compare(float, float)์ Double.compare(double, double)๋ก ๋น๊ต
- Float.NaN, -0.0f, ํน์ํ ๋ถ๋์์ ๊ฐ ๋ฑ์ ๋ค๋ค์ผ ํ๊ธฐ ๋๋ฌธ์
- null๋ ์ ์ ๊ฐ์ผ๋ก ์ทจ๊ธํ๋ ์ฐธ์กฐ ํ์
ํ๋์ ๊ฒฝ์ฐ, ์ ์ ๋ฉ์๋์ธ Objects.equals(Object, Object)๋ก ๋น๊ต
- NullPointerException ๋ฐฉ์ง๋ฅผ ์ํจ
- ๋น๊ตํ๊ธฐ ๋ณต์กํ ํ๋๋ฅผ ๊ฐ์ง ํด๋์ค์ธ ๊ฒฝ์ฐ, ๊ทธ ํ๋์ ํ์คํ(canonical form)์ ์ ์ฅํด๋ ํ ํ์คํ๋ผ๋ฆฌ ๋น๊ต
- ํนํ ๋ถ๋ณ ํด๋์ค์ ์ ๊ฒฉ์
- ๊ฐ๋ณ ๊ฐ์ฒด๋ผ๋ฉด ๊ฐ์ด ๋ฐ๋ ๋๋ง๋ค ํ์คํ์ ์ต์ ์ํ๋ก ๊ฐฑ์ ํด์ค์ผ ํจ
*์ด๋ค ํ๋๋ฅผ ๋จผ์ ๋น๊ตํ๋๋๊ฐ equals์ ์ฑ๋ฅ์ ์ข์ฐํ๊ธฐ๋ ํจ!
- ์ต์์ ์ฑ๋ฅ์ ๋ฐ๋๋ค๋ฉด, ๋ค๋ฅผ ๊ฐ๋ฅ์ฑ์ด ๋ ํฌ๊ฑฐ๋ ๋น๊ตํ๋ ๋น์ฉ์ด ์ผ ํ๋๋ฅผ ๋จผ์ ๋น๊ตํ์
์ฝ๋ 10-6 ์ ํ์ ์ธ equals ๋ฉ์๋์ ์
public final class PhoneNumber { private final short areaCode, prefix, lineNum; ... @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof PhoneNumber)) return false; PhoneNumber pn = (PhoneNumber) o; return pn.liNum == this.lineNum && pn.prefix == this.prefix && pn.areaCode == this.areaCode; } ... }
โถ๏ธ ์ฃผ์์ฌํญ
1. equals๋ฅผ ์ฌ์ ์ํ ๋ hashCode๋ ๋ฐ๋์ ์ฌ์ ์ํ์
2. ๋๋ฌด ๋ณต์กํ๊ฒ ํด๊ฒฐํ๋ ค ๋ค์ง ๋ง์
- ํ๋๋ค์ ๋์น์ฑ๋ง ๊ฒ์ฌํด๋ equals ๊ท์ฝ์ ์ด๋ ต์ง ์๊ฒ ์งํฌ ์ ์์
3. Object ์ธ์ ํ์ ์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ๋ equals ๋ฉ์๋๋ ์ ์ธํ์ง ๋ง์
//์๋ชป๋ ์ public boolean equals(MyClass o) { ... }
๐ํต์ฌ ์ ๋ฆฌ
- ๊ผญ ํ์ํ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด equals๋ฅผ ์ฌ์ ์ํ์ง ๋ง์
- ๋ง์ ๊ฒฝ์ฐ์ Object์ equals๊ฐ ์ํ๋ ๋น๊ต๋ฅผ ์ ํํ ์ํํด์ค
- ์ฌ์ ์ํ ๋๋ ๊ทธ ํด๋์ค์ ํต์ฌ ํ๋๋ฅผ ๋ชจ๋, ๋ค์ฏ ๊ฐ์ง ๊ท์ฝ์ ํ์คํ ์ง์ผ๊ฐ๋ฉฐ ๋น๊ตํด์ผ ํจ
'DevBook > Effective Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์์ดํ 12. toString์ ํญ์ ์ฌ์ ์ํ๋ผ (0) 2023.05.07 ์์ดํ 11. equals๋ฅผ ์ฌ์ ์ํ๋ ค๊ฑฐ๋ hashCode๋ ์ฌ์ ์ํ๋ผ (0) 2023.05.07 3์ฅ - ๋ชจ๋ ๊ฐ์ฒด์ ๊ณตํต ๋ฉ์๋ (0) 2023.05.06 ์์ดํ 9. try-finally๋ณด๋ค๋ try-with-resources๋ฅผ ์ฌ์ฉํ๋ผ (0) 2023.05.06 ์ ๋ค๋ฆญ Item 26 - ๋ก ํ์ ์ ์ฌ์ฉํ์ง ๋ง๋ผ (0) 2022.01.29