ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ์•„์ดํ…œ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๊ฐ€ ์›ํ•˜๋Š” ๋น„๊ต๋ฅผ ์ •ํ™•ํžˆ ์ˆ˜ํ–‰ํ•ด์คŒ
    • ์žฌ์ •์˜ํ•  ๋•Œ๋Š” ๊ทธ ํด๋ž˜์Šค์˜ ํ•ต์‹ฌ ํ•„๋“œ๋ฅผ ๋ชจ๋‘, ๋‹ค์„ฏ ๊ฐ€์ง€ ๊ทœ์•ฝ์„ ํ™•์‹คํžˆ ์ง€์ผœ๊ฐ€๋ฉฐ ๋น„๊ตํ•ด์•ผ ํ•จ

    ๋Œ“๊ธ€

Designed by Tistory.