๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” - ๋ชจ๋“  ๊ฐ์ฒด์˜ ๊ณตํ†ต ๋ฉ”์„œ๋“œ

19565 ๋‹จ์–ด Java๋…์„œ20222022

3์žฅ - ๋ชจ๋“  ๊ฐ์ฒด์˜ ๊ณตํ†ต ๋ฉ”์„œ๋“œ


๐Ÿ’ก equals๋Š” ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€์ผœ ์žฌ์ •์˜ํ•˜๋ผ

โ€œ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ฉด equals๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ๋ง์žโ€

1. ์žฌ์ •์˜๋ฅผ ์ตœ๋Œ€ํ•œ ํ”ผํ•˜์ž

  • equals ๋ฉ”์„œ๋“œ๋Š” ์žฌ์ •์˜ํ•˜๊ธฐ ์‰ฌ์›Œ ๋ณด์ด์ง€๋งŒ ๊ณณ๊ณณ์— ํ•จ์ •์ด ๋„์‚ฌ๋ฆฌ๊ณ  ์žˆ์Œ
  • ๋ฌธ์ œ๋ฅผ ํšŒํ”ผํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๊ธธ์€ ์•„์˜ˆ ์žฌ์ •์˜ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ
  • ๋งŽ์€ ๊ฒฝ์šฐ์— Object์˜ equals๊ฐ€ ๋น„๊ต์  ์ •ํ™•ํžˆ ์ˆ˜ํ–‰ํ•ด ์คŒ

2. equals ์žฌ์ •์˜๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ

  • ๊ฐ์ฒด ์‹๋ณ„์„ฑ์ด ์•„๋‹ˆ๋ผ ๋…ผ๋ฆฌ์  ๋™์น˜์„ฑ์„ ํ™•์ธํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ƒ์œ„ ํด๋ž˜์Šค์˜ equals๊ฐ€ ๋…ผ๋ฆฌ์  ๋™์น˜์„ฑ์„ ๋น„๊ตํ•˜๋„๋ก ์žฌ์ •์˜๋˜์ง€ ์•Š์•˜์„ ๋•Œ.
    • ๊ฐ์ฒด ์‹๋ณ„์„ฑ : ๋‘ ๊ฐ์ฒด๊ฐ€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ฐ™์€๊ฐ€(์ฃผ์†Œ), == ์—ฐ์‚ฐ์ž๋กœ ํ™•์ธ
    • ๋…ผ๋ฆฌ์  ๋™์น˜์„ฑ : ๊ฐ’์ด ๊ฐ™์€๊ฐ€?, equals ๋ฉ”์„œ๋“œ๋กœ ํ™•์ธ
  • ์ฃผ๋กœ Integer, String์ฒ˜๋Ÿผ ๊ฐ’์„ ํ‘œํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์ด์— ํ•ด๋‹น ํ•จ.

3. equals ์ผ๋ฐ˜ ๊ทœ์•ฝ

โ†’ equals ๋ฉ”์„œ๋“œ ์žฌ์ •์˜ ์‹œ, ๋ฐ˜๋“œ์‹œ ์•„๋ž˜ ์ผ๋ฐ˜๊ทœ์•ฝ์„ ๋”ฐ๋ผ์•ผ ํ•จ.

์š”๊ฑด์„ค๋ช…
๋ฐ˜์‚ฌ์„ฑ(reflexivity)null์ด ์•„๋‹Œ ๋ชจ๋“  ์ฐธ์กฐ ๊ฐ’ x์— ๋Œ€ํ•ด, x.equals(x)๋Š” true๋‹ค.
๋Œ€์นญ์„ฑ(symmetry)null์ด ์•„๋‹Œ ๋ชจ๋“  ์ฐธ์กฐ ๊ฐ’ x, y์— ๋Œ€ํ•ด, x.equals(y)๊ฐ€ true๋ฉด y.equals(x)๋„ true๋‹ค.
์ถ”์ด์„ฑ(transitivity)null์ด ์•„๋‹Œ ๋ชจ๋“  ์ฐธ์กฐ ๊ฐ’ x, y, z์— ๋Œ€ํ•ด x.equals(y)๊ฐ€ true์ด๊ณ , y.equals(z)๊ฐ€ true๋ฉด x.equals(z)๋„ true๋‹ค.
์ผ๊ด€์„ฑ(consistency)null์ด ์•„๋‹Œ ๋ชจ๋“  ์ฐธ์กฐ ๊ฐ’ x, y์— ๋Œ€ํ•ด x.equals(y)๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ํ˜ธ์ถœํ•˜๋ฉด ํ•ญ์ƒ true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ํ•ญ์ƒ false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
null-์•„๋‹˜null์ด ์•„๋‹Œ ๋ชจ๋“  ์ฐธ์กฐ ๊ฐ’ x์— ๋Œ€ํ•ด, x.equals(null)์€ false๋‹ค.

4. AutoValue ํ”„๋ ˆ์ž„์›Œํฌ

  • equals ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ฒ ์ €ํžˆ ์ง€ํ‚ค๋ฉฐ equals๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ์ผ์€ ์ง€๋ฃจํ•˜๊ณ  ์‰ฝ์ง€ ์•Š๋‹ค.
  • ๊ตฌ๊ธ€์˜ AutoValue ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ด ์ž‘์—…์„ ๋Œ€์‹ ํ•ด ์คŒ.
  • ํด๋ž˜์Šค์— ์–ด๋…ธํ…Œ์ด์…˜ ํ•˜๋‚˜๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด equals ๋ฉ”์„œ๋“œ๋ฅผ ์•Œ์•„์„œ ์ž‘์„ฑํ•ด์ฃผ๋ฉฐ, ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๊ณผ ๊ทผ๋ณธ์ ์œผ๋กœ ๋˜‘๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด ์คŒ.

โ†’ ๋ถ€์ฃผ์˜ํ•œ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด AutoValue ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ ๊ทน ํ™œ์šฉํ•˜์ž.



๐Ÿ’ก equals๋ฅผ ์žฌ์ •์˜ํ•˜๋ ค๊ฑฐ๋“  hashCode๋„ ์žฌ์ •์˜ํ•˜๋ผ

โ€œequals๋ฅผ ์žฌ์ •์˜ํ•œ ํด๋ž˜์Šค ๋ชจ๋‘์—์„œ hashCode๋„ ์žฌ์ •์˜ํ•ด์•ผ ํ•œ๋‹คโ€

1. hashCode ์žฌ์ •์˜ ํ•„์š”์„ฑ

  • equals๋ฅผ ์žฌ์ •์˜ํ•œ ํด๋ž˜์Šค์—์„œ hashCode๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ์•Š์œผ๋ฉด, hashCode ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์–ด๊ธฐ๊ฒŒ ๋˜์–ด ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ HashMap์ด๋‚˜ HashSet ๊ฐ™์€ ์ปฌ๋ ‰์…˜์˜ ์›์†Œ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋จ
  • hashCode๋ฅผ ์žฌ์ •์˜ ํ•  ์‹œ, ๋ฐ˜๋“œ์‹œ ์•„๋ž˜ ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ๋”ฐ๋ผ์•ผ ํ•จ
์„ค๋ช…
1equals ๋น„๊ต์— ์‚ฌ์šฉ๋˜๋Š” ์ •๋ณด๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๊ทธ ๊ฐ์ฒด์˜ hashCode ๋ฉ”์„œ๋“œ๋Š” ๋ช‡ ๋ฒˆ์„ ํ˜ธ์ถœํ•ด๋„ ์ผ๊ด€๋˜๊ฒŒ ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.
๋‹จ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ค์‹œ ์‹คํ–‰ํ•œ๋‹ค๋ฉด ์ด ๊ฐ’์ด ๋‹ฌ๋ผ์ ธ๋„ ์ƒ๊ด€์—†๋‹ค.
2equals(Object)๊ฐ€ ๋‘ ๊ฐ์ฒด๋ฅผ ๊ฐ™๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค๋ฉด, ๋‘ ๊ฐ์ฒด์˜ hashCode๋Š” ๋˜‘๊ฐ™์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.
3equals(Object)๊ฐ€ ๋‘ ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฅด๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋”๋ผ๋„, ๋‘ ๊ฐ์ฒด์˜ hashCode๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ํ•„์š”๋Š” ์—†๋‹ค. ๋‹จ, ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค๋ฅธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ด์‹œํ…Œ์ด๋ธ”์˜ ์„ฑ๋Šฅ์ด ์ข‹์•„์ง„๋‹ค.

2. AutoValue ํ”„๋ ˆ์ž„์›Œํฌ

  • hashCode ์ผ๋ฐ˜ ๊ทœ์•ฝ์„ ์ง€ํ‚ค๋ฉฐ ์žฌ์ •์˜ํ•˜๋Š” ์ผ์€ ์–ด๋ ต์ง€๋Š” ์•Š์ง€๋งŒ ์กฐ๊ธˆ ๋”ฐ๋ถ„ํ•œ ์ผ

โ†’ AutoValue ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ‹์ง„ equals์™€ hashCode๋ฅผ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด ์คŒ! ์ ๊ทนํ™œ์šฉํ•˜์ž



๐Ÿ’ก toString์„ ํ•ญ์ƒ ์žฌ์ •์˜ํ•˜๋ผ

โ€œ๋ชจ๋“  ๊ตฌ์ฒด ํด๋ž˜์Šค์—์„œ Object์˜ toString์„ ์žฌ์ •์˜ํ•˜์žโ€

1. Object์˜ ๊ธฐ๋ณธ toString ๋ฉ”์„œ๋“œ

  • ๋‹จ์ˆœํžˆ ํด๋ž˜์Šค์ด๋ฆ„@16์ง„์ˆ˜๋กœํ‘œ์‹œํ•œ_ํ•ด์‹œ์ฝ”๋“œ ๋ฐ˜ํ™˜(์œ ์ตํ•˜์ง€ ์•Š์€ ์ •๋ณด)
  • toString์˜ ๊ทœ์•ฝ : ๋ชจ๋“  ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋ผ
  • ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„, ๋‹ค๋ฅธ ์–ด๋”˜๊ฐ€์—์„œ ์“ฐ์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ
    • ex) println, printf, ๋ฌธ์ž์—ด ์—ฐ๊ฒฐ ์—ฐ์‚ฐ์ž(+), ๋””๋ฒ„๊ฑฐ๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ

โ†’ ๊ฐ„๊ฒฐํ•˜๋ฉด์„œ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ํ˜•ํƒœ์˜ ์œ ์ตํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์žฌ์ •์˜ํ•˜์ž


2. ์žฌ์ •์˜ ๋ฐฉ๋ฒ•

  • ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง„ ์ฃผ์š” ์ •๋ณด ๋ชจ๋‘๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒŒ ์ข‹์Œ
  • ํฌ๋งท์„ ๋ช…์‹œํ•˜๋“  ์•„๋‹ˆ๋“  ์˜๋„๋ฅผ ๋ช…ํ™•ํžˆ ํ•ด์•ผํ•จ.
  • ํฌ๋งท์„ ๋ช…์‹œํ•œ ๊ฒฝ์šฐ
    • ์žฅ์  : ํ‘œ์ค€์ , ๋ช…ํ™•, ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ์Œ
    • ๋‹จ์  : ํ‰์ƒ ๊ทธ ํฌ๋งท์— ์–ฝ๋งค์ž„
    • ํฌ๋งท์„ ๋ช…์‹œํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค๋ฉด ๋ช…์‹œํ•œ ํฌ๋งท์— ๋งž๋Š” ๋ฌธ์ž์—ด๊ณผ ๊ฐ์ฒด๋ฅผ ์ƒํ˜ธ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ •์  ํŒฉํ„ฐ๋ฆฌ๋‚˜ ์ƒ์„ฑ์ž๋ฅผ ํ•จ๊ป˜ ์ œ๊ณตํ•ด์ฃผ๋ฉด ์ข‹์Œ
		/**
     * ์ด ์ „ํ™”๋ฒˆํ˜ธ์˜ ๋ฌธ์ž์—ด ํ‘œํ˜„์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
     * ์ด ๋ฌธ์ž์—ด์€ "XXX-YYY-ZZZZ" ํ˜•ํƒœ์˜ 12๊ธ€์ž๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
     * XXX๋Š” ์ง€์—ญ ์ฝ”๋“œ, YYY๋Š” ํ”„๋ฆฌํ”ฝ์Šค, ZZZZ๋Š” ๊ฐ€์ž…์ž ๋ฒˆํ˜ธ๋‹ค.
     * ๊ฐ๊ฐ์˜ ๋Œ€๋ฌธ์ž๋Š” 10์ง„์ˆ˜ ์ˆซ์ž ํ•˜๋‚˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
     *
     * ์ „ํ™”๋ฒˆํ˜ธ์˜ ๊ฐ ๋ถ€๋ถ„์˜ ๊ฐ’์ด ๋„ˆ๋ฌด ์ž‘์•„์„œ ์ž๋ฆฟ์ˆ˜๋ฅผ ์ฑ„์šธ ์ˆ˜ ์—†๋‹ค๋ฉด,
     * ์•ž์—์„œ๋ถ€ํ„ฐ 0์œผ๋กœ ์ฑ„์›Œ๋‚˜๊ฐ„๋‹ค. ์˜ˆ์ปจ๋Œ€ ๊ฐ€์ž…์ž ๋ฒˆํ˜ธ๊ฐ€ 123์ด๋ผ๋ฉด
     * ์ „ํ™”๋ฒˆํ˜ธ์˜ ๋งˆ์ง€๋ง‰ ๋„ค ๋ฌธ์ž๋Š” "0123"์ด ๋œ๋‹ค.
     */
    @Override public String toString() {
        return String.format("%03d-%03d-%04d",
                areaCode, prefix, lineNum);
    }
  • ํฌ๋งท์„ ๋ช…์‹œํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
	/**
     * ์ด ์•ฝ๋ฌผ์— ๊ด€ํ•œ ๋Œ€๋žต์ ์ธ ์„ค๋ช…์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
		 * ๋‹ค์Œ์€ ์ด ์„ค๋ช…์˜ ์ผ๋ฐ˜์ ์ธ ํ˜•ํƒœ์ด๋‚˜, 
		 * ์ƒ์„ธํ˜•์‹์€ ์ •ํ•ด์ง€์ง€ ์•Š์•˜์œผ๋ฉฐ ํ–ฅํ›„ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋‹ค.
		 *
		 * "[์•ฝ๋ฌผ #9: ์œ ํ˜•=์‚ฌ๋ž‘, ๋ƒ„์ƒˆ=ํ…Œ๋ ˆ๋นˆ์œ , ๊ฒ‰๋ชจ์Šต=๋จน๋ฌผ]"
     */
    @Override public String toString() { ... }
  • ํฌ๋งท ๋ช…์‹œ์—ฌ๋ถ€์— ๊ด€๊ณ„์—†์ด toString์ด ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์— ํฌํ•จ๋œ ์ •๋ณด๋ฅผ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ๋Š” API๋ฅผ ์ œ๊ณตํ•˜์ž. (getter)

3. AutoValue ํ”„๋ ˆ์ž„์›Œํฌ

  • AutoValue ํ”„๋ ˆ์ž„์›Œํฌ๋Š” toString๋„ ์ƒ์„ฑํ•ด ์คŒ.
  • AutoValue ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ฐ ํ•„๋“œ์˜ ๋‚ด์šฉ์„ ๋ฉ‹์ง€๊ฒŒ ๋‚˜ํƒ€๋‚ด ์ฃผ๊ธฐ๋Š” ํ•˜์ง€๋งŒ ํด๋ž˜์Šค์˜ โ€˜์˜๋ฏธโ€™๊นŒ์ง€ ํŒŒ์•…ํ•˜์ง€๋Š” ๋ชป ํ•จ
  • ์˜ˆ๋ฅผ ๋“ค์–ด ์ „ํ™”๋ฒˆํ˜ธ ๊ฐ™์€ ํฌ๋งท(XXX-YYY-ZZZZ)์— ๋”ฐ๋ผ ๋ฐ˜ํ™˜ํ•ด์•ผํ•˜๋Š” toString์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š๊ณ , ์ผ๋ฐ˜์ ์ธ ์ •๋ณด๋“ค๋งŒ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์ ํ•ฉํ•จ.

โ†’ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜์ž



๐Ÿ’ก clone ์žฌ์ •์˜๋Š” ์ฃผ์˜ํ•ด์„œ ์ง„ํ–‰ํ•˜๋ผ

โ€œ๋ณต์ œ ๊ธฐ๋Šฅ์€ ์ƒ์„ฑ์ž์™€ ํŒฉํ„ฐ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ตœ๊ณ โ€

1. Cloneable ์ธํ„ฐํŽ˜์ด์Šค์™€ clone ๋ฉ”์„œ๋“œ

  • Cloneable ์ธํ„ฐํŽ˜์ด์Šค
    • ๋ณต์ œํ•ด๋„ ๋˜๋Š” ํด๋ž˜์Šค์ž„์„ ๋ช…์‹œํ•˜๋Š” ์šฉ๋„์˜ ๋ฏน์Šค์ธ ์ธํ„ฐํŽ˜์ด์Šค(mixin interface)
    • Object์˜ protected ๋ฉ”์„œ๋“œ์ธ clone์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ๊ฒฐ์ •
  • Object์˜ clone ๋ฉ”์„œ๋“œ
    • Cloneable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์—์„œ clone์„ ํ˜ธ์ถœํ•˜๋ฉด ๊ทธ ๊ฐ์ฒด์˜ ํ•„๋“œ๋“ค์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋ณต์‚ฌํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜

2. Cloneable & clone์˜ ๋ฌธ์ œ์ 

  • ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ •์˜ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค๊ณ  ์„ ์–ธํ•˜๋Š” ํ–‰์œ„
    • but, Cloneable์˜ ๊ฒฝ์šฐ์—๋Š” ์ƒ์œ„ ํด๋ž˜์Šค์— ์ •์˜๋œ protected ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ
  • Cloneable ์•„ํ‚คํ…์ฒ˜๋Š” โ€˜๊ฐ€๋ณ€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํ•„๋“œ๋Š” final๋กœ ์„ ์–ธํ•˜๋ผโ€™๋Š” ์ผ๋ฐ˜ ์šฉ๋ฒ•๊ณผ ์ถฉ๋Œํ•œ๋‹ค.
    • ๋ณต์ œํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ผ๋ถ€ ํ•„๋“œ์—์„œ final ํ•œ์ •์ž๋ฅผ ์ œ๊ฑฐํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Œ
  • Cloneable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” clone ๋ฉ”์„œ๋“œ๋ฅผ public์œผ๋กœ ์ œ๊ณตํ•˜๋ฉฐ, ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ ๋„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ
  • Object์˜ clone ๋ฉ”์„œ๋“œ๋Š” ๋™๊ธฐํ™”๋ฅผ ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ super.cloneํ˜ธ์ถœ ์™ธ์— ๋‹ค๋ฅธ ํ•  ์ผ์ด ์—†๋”๋ผ๋„ clone์„ ์žฌ์ •์˜ ํ›„ ๋™๊ธฐํ™”ํ•ด์ค˜์•ผ ํ•จ

3. clone ์žฌ์ •์˜ ๋ฐฉ๋ฒ•

  1. Cloneable ๊ตฌํ˜„
  2. ์ ‘๊ทผ์ œํ•œ์ž๋Š” public, ๋ฐ˜ํ™˜ ํƒ€์ž…์€ ํด๋ž˜์Šค ์ž์‹ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ์žฌ์ •์˜
  3. ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ๋Š” ๊ฐ€์žฅ ๋จผ์ € super.clone์„ ํ˜ธ์ถœํ•œ ํ›„ ํ•„์š”ํ•œ ํ•„๋“œ๋ฅผ ์ „๋ถ€ ์ ์ ˆํžˆ ์ˆ˜์ •

4. ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€ ๋ณต์‚ฌ ํŒฉํ„ฐ๋ฆฌ

  • ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€ ๋ณต์‚ฌ ํŒฉํ„ฐ๋ฆฌ๋Š” ์–ธ์–ด ๋ชจ์ˆœ์ ์ด๊ณ  ์œ„ํ—˜์ฒœ๋งŒํ•œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜(์ƒ์„ฑ์ž๋ฅผ ์“ฐ์ง€ ์•Š๋Š” ๋ฐฉ์‹)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
  • ์—‰์„ฑํ•˜๊ฒŒ ๋ฌธ์„œํ™”๋œ ๊ทœ์•ฝ(clone ๋ฉ”์„œ๋“œ์˜ ์ผ๋ฐ˜ ๊ทœ์•ฝ)์— ๊ธฐ๋Œ€์ง€ ์•Š๊ณ , ์ •์ƒ์ ์ธ finalํ•„๋“œ ์šฉ๋ฒ•๊ณผ๋„ ์ถฉ๋Œํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ถˆํ•„์š”ํ•œ ๊ฒ€์‚ฌ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€์ง€ ์•Š๊ณ , ํ˜•๋ณ€ํ™˜๋„ ํ•„์š”ํ•˜์ง€ ์•Š์Œ.
  • ๋ณต์‚ฌ ์ƒ์„ฑ์ž ์˜ˆ์‹œ
// ์ž์‹ ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ์ƒ์„ฑ์ž
public Yum(Yum yum) { ... };
  • ๋ณต์‚ฌ ํŒฉํ„ฐ๋ฆฌ ์˜ˆ์‹œ
// ๋ณต์‚ฌ ์ƒ์„ฑ์ž๋ฅผ ๋ชจ๋ฐฉํ•œ ์ •์  ํŒฉํ„ฐ๋ฆฌ
public static Yum newInstance(Yum yum) { ... };

โ†’ ์ƒˆ๋กœ์šด ์ธํ„ฐํŽ˜์ด์Šค๋‚˜ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ, Cloneable ์‚ฌ์šฉ์„ ์ ˆ๋Œ€ ์ง€์–‘ํ•˜์ž. ๋Œ€์‹  ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€ ๋ณต์‚ฌ ํŒฉํ„ฐ๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜์ž



๐Ÿ’ก Comparable์„ ๊ตฌํ˜„ํ• ์ง€ ๊ณ ๋ คํ•˜๋ผ

โ€œ์ˆœ์„œ๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ๊ฐ’ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค๋ฉด Comparable์„ ๊ตฌํ˜„ํ•˜์žโ€

1. Comparable ์ธํ„ฐํŽ˜์ด์Šค

public interface Comparable<T> {
		int compareTo(T t);
}
  • Comparable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค๋Š” ๊ฒƒ์€ ๊ทธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋“ค์—๋Š” ์ž์—ฐ์ ์ธ ์ˆœ์„œ(natural order)๊ฐ€ ์žˆ์Œ์„ ๋œป ํ•จ
  • Comparable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด ๋“ค์˜ ๋ฐฐ์—ด์€ ์•„๋ž˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ์†์‰ฝ๊ฒŒ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ์Œ.
Arrays.sort(a);
  • ๊ฒ€์ƒ‰, ๊ทน๋‹จ๊ฐ’ ๊ณ„์‚ฐ, ์ž๋™ ์ •๋ ฌ๋˜๋Š” ์ปฌ๋ ‰์…˜ ๊ด€๋ฆฌ๋„ ์—ญ์‹œ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Œ.

2. compareTo ๋ฉ”์„œ๋“œ ์ผ๋ฐ˜ ๊ทœ์•ฝ

์š”๊ฑด์„ค๋ช…
๋Œ€์นญ์„ฑComparable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ๋ชจ๋“  x, y์— ๋Œ€ํ•ด sgn(x.compartTo(y)) == -sgn.(y.compareTo(x))์—ฌ์•ผ ํ•œ๋‹ค(๋”ฐ๋ผ์„œ x.compareTo(y)๋Š” y.compareTo(x)๊ฐ€ ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ๋•Œ์— ํ•œํ•ด ์˜ˆ์™ธ๋ฅผ ๋˜์ ธ์•ผ ํ•œ๋‹ค).
์ถ”์ด์„ฑComparable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ์ถ”์ด์„ฑ์„ ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, (x.compareTo(y) > 0 && y.compareTo(z) > 0)์ด๋ฉด x.compareTo(z) > 0์ด๋‹ค.
๋ฐ˜์‚ฌ์„ฑComparable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ๋ชจ๋“  z์— ๋Œ€ํ•ด x.compareTo(y) == 0์ด๋ฉด sgn(x.compareTo(z)) == sgn(y.compareTo(z))๋‹ค.
๋™์น˜์„ฑ ํ…Œ์ŠคํŠธ์˜ ๊ฒฐ๊ณผ๊ฐ€ equals์™€ ๋™์ผํ•œ๊ฐ€์ด๋ฒˆ ๊ถŒ๊ณ ๊ฐ€ ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ๊ผญ ์ง€ํ‚ค๋Š” ๊ฒŒ ์ข‹๋‹ค. (x.compareTo(y) == 0) == (x.equals(y))์—ฌ์•ผ ํ•œ๋‹ค. Comparable์„ ๊ตฌํ˜„ํ•˜๊ณ  ์ด ๊ถŒ๊ณ ๋ฅผ ์ง€ํ‚ค์ง€ ์•Š๋Š” ๋ชจ๋“  ํด๋ž˜์Šค๋Š” ๊ทธ ์‚ฌ์‹ค์„ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ช…์‹œํ•˜๋ฉด ์ ๋‹นํ•  ๊ฒƒ์ด๋‹ค.

โ€์ฃผ์˜: ์ด ํด๋ž˜์Šค์˜ ์ˆœ์„œ๋Š” equals ๋ฉ”์„œ๋“œ์™€ ์ผ๊ด€๋˜์ง€ ์•Š๋‹ค.โ€

3. ๋น„๊ต์ž

  • compareTo ๋ฉ”์„œ๋“œ์—์„œ ๊ด€๊ณ„ ์—ฐ์‚ฐ์ž <์—ฐ์‚ฐ์ž๋‚˜ >๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ „ ๋ฐฉ์‹์€ ๊ฑฐ์ถ”์žฅ์Šค๋Ÿฝ๊ณ  ์˜ค๋ฅ˜๋ฅผ ์œ ๋ฐœํ•˜๋‹ˆ, ๋น„์ถ”์ฒœ
  • ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ๋น„๊ตํ•  ๋•Œ
  1. ์ž๋ฐ”๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋น„๊ต์ž ์‚ฌ์šฉ, ex. String.CASE_INSENSITIVE_ORDER
public final class CaseInsensitiveString implements Comparable<CaseInsensitiveString> {
    // ์ž๋ฐ”๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋น„๊ต์ž๋ฅผ ์‚ฌ์šฉํ•ด ํด๋ž˜์Šค๋ฅผ ๋น„๊ตํ•œ๋‹ค.
    public int compareTo(CaseInsensitiveString cis) {
        return String.CASE_INSENSITIVE_ORDER.compare(s, cis.s);
    }
		... // ๋‚˜๋จธ์ง€ ์ฝ”๋“œ ์ƒ๋žต
}
  1. ๋น„๊ต์ž ์ƒ์„ฑ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ
public final class PhoneNumber implements Cloneable, Comparable<PhoneNumber> {
    //๋น„๊ต์ž ์ƒ์„ฑ ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•œ ๋น„๊ต์ž
    private static final Comparator<PhoneNumber> COMPARATOR =
            comparingInt((PhoneNumber pn) -> pn.areaCode)
                    .thenComparingInt(pn -> pn.prefix)
                    .thenComparingInt(pn -> pn.lineNum);

    public int compareTo(PhoneNumber pn) {
        return COMPARATOR.compare(this, pn);
    }
		... // ๋‚˜๋จธ์ง€ ์ฝ”๋“œ ์ƒ๋žต
}
  • ๊ธฐ๋ณธ ํƒ€์ž…์„ ๋น„๊ตํ•  ๋•Œ : ๋ฐ•์‹ฑ๋œ ๊ธฐ๋ณธ ํƒ€์ž…๋“ค์˜ compare๋ฉ”์„œ๋“œ ์‚ฌ์šฉ
// ๊ธฐ๋ณธ ํƒ€์ž… ํ•„๋“œ๊ฐ€ ์—ฌ๋Ÿฟ์ผ ๋•Œ์˜ ๋น„๊ต์ž
public int compareTo(PhoneNumber pn) {
    int result = Short.compare(areaCode, pn.areaCode);
    if (result == 0)  {
        result = Short.compare(prefix, pn.prefix);
        if (result == 0)
            result = Short.compare(lineNum, pn.lineNum);
    }
    return result;
}

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ