item 19 Jung inchul - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

์ƒ์†์šฉ ํด๋ž˜์Šค๋Š” ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋“ค์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ด์šฉํ•˜๋Š”์ง€(์ž๊ธฐ์‚ฌ์šฉ) ๋ฌธ์„œ๋กœ ๋‚จ๊ฒจ์•ผ ํ•œ๋‹ค. ๋ง๋ถ™์—ฌ์„œ ์–ด๋–ค ์ˆœ์„œ๋กœ ํ˜ธ์ถœํ•˜๋Š”์ง€, ๊ฐ๊ฐ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๊ฐ€ ์ด์–ด์ง€๋Š” ์ฒ˜๋ฆฌ์— ์–ด๋–ค ์˜ํ–ฅ์„ ์ฃผ๋Š”์ง€๋„ ๋‹ด์•„์•ผ ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์‹์€ "์ข‹์€ API ๋ฌธ์„œ๋ž€ '์–ด๋–ป๊ฒŒ'๊ฐ€ ์•„๋‹Œ '๋ฌด์—‡'์„ ํ•˜๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•ด์•ผ ํ•œ๋‹ค"๋ผ๋Š” ๊ฒฉ์–ธ ๊ณผ๋Š” ๋Œ€์น˜๋˜์ง€ ์•Š๋‚˜? ๊ทธ๋ ‡๋‹ค. ์ƒ์†์ด ์บก์Šํ™”๋ฅผ ํ•ด์น˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ์–ด๋‚˜๋Š” ์•ˆํƒ€๊นŒ์šด ํ˜„์‹ค์ด๋‹ค.

@implSpec ํƒœ๊ทธ๋Š” ์ž๋ฐ” 8์—์„œ ์ฒ˜์Œ ๋„์ž…๋˜์–ด ์ž๋ฐ” 9๋ถ€ํ„ฐ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‚ฌ์šฉ ๋˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

ํšจ์œจ์ ์ธ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ํฐ ์–ด๋ ค์›€ ์—†์ด ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๋™์ž‘ ๊ณผ์ • ์ค‘๊ฐ„์— ๋ผ์–ด๋“ค ์ˆ˜ ์žˆ๋Š” ํ›…(hook)์„ ์ž˜ ์„ ๋ณ„ํ•˜์—ฌ protected ๋ฉ”์„œ๋“œ ํ˜•ํƒœ๋กœ ๊ณต๊ฐœํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

java.util.AbstractList์˜ removeTange ๋ฉ”์„œ๋“œ๋ฅผ ์˜ˆ๋กœ ์‚ดํŽด๋ณด์ž

protected void removeRange(int fromIndex, int toIndex)

...
 ์ด ๋ฆฌ์ŠคํŠธ๋Š” ํ˜น์€ ์ด ๋ฆฌ์ŠคํŠธ์˜ ๋ถ€๋ถ„๋ฆฌ์ŠคํŠธ์— ์ •์˜๋œ clear ์—ฐ์‚ฐ์ด ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 

List ๊ตฌํ˜„์ฒด์˜ ์ตœ์ข… ์‚ฌ์šฉ์ž๋Š” removeRange ๋ฉ”์„œ๋“œ์— ๊ด€์‹ฌ์ด ์—†๋‹ค. ๊ทธ๋Ÿผ์—๋„ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ ์ด์œ ๋Š” ๋‹จ์ง€ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๋ถ€๋ถ„๋ฆฌ์ŠคํŠธ์˜ clear ๋ฉ”์„œ๋“œ๋ฅผ ๊ณ ์„ฑ๋Šฅ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋‹ค. removeRange ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ clear ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ œ๊ณฑ์— ๋น„๋ก€ํ•ด ์„ฑ๋Šฅ์ด ๋Š๋ ค์ง€๊ฑฐ๋‚˜ ๋ถ€๋ถ„๋ฆฌ์ŠคํŠธ์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋ฐ‘๋ฐ”๋‹ฅ๋ถ€ํ„ฐ ์ƒˆ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ƒ์†์šฉ ํด๋ž˜์Šค๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์–ด๋–ค ๋ฉ”์„œ๋“œ๋ฅผ protected๋กœ ๋…ธ์ถœํ•ด์•ผ ํ• ์ง€๋Š” ์–ด๋–ป๊ฒŒ ๊ฒฐ์ •ํ• ๊นŒ?

์ •๋‹ต์€ ์—†๋‹ค. ์‹ฌ์‚ฌ์ˆ™๊ณ ํ•ด์„œ ์ž˜ ์˜ˆ์ธกํ•ด๋ณธ ๋‹ค์Œ, ์‹ค์ œ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‹œํ—˜ ํ•ด๋ณด๋Š” ๊ฒƒ์ด ์ตœ์„ ์ด๋‹ค.

์ƒ์†์šฉ ํด๋ž˜์Šค๋ฅผ ์‹œํ—˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ง์ ‘ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋Š” ๊ฒƒ์ด '์œ ์ผ'ํ•˜๋‹ค. ๊ผญ ํ•„์š”ํ•œ protected ๋ฉค๋ฒ„๋ฅผ ๋†“์ณค๋‹ค๋ฉด ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ๊ทธ ๋นˆ์ž๋ฆฌ๊ฐ€ ํ™•์—ฐํžˆ ๋“œ๋Ÿฌ๋‚œ๋‹ค. ๊ฑฐ๊พธ๋กœ, ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค ๋•Œ๊นŒ์ง€ ์ „ํ˜€ ์“ฐ์ด์ง€ ์•Š๋Š” protected ๋ฉค๋ฒ„๋Š” ์‚ฌ์‹ค private ์ด์—ฌ์•ผ ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.

์ƒ์†์šฉ์œผ๋กœ ์„ค๊ณ„ํ•œ ํด๋ž˜์Šค๋Š” ๋ฐฐํฌ ์ „์— ๋ฐ˜๋“œ์‹œ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ๊ฒ€์ฆํ•ด์•ผ ํ•œ๋‹ค.

๋˜ํ•œ, ์ƒ์†์šฉ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋Š” ์ง์ ‘์ ์œผ๋กœ๋“  ๊ฐ„์ ‘์ ์œผ๋กœ๋“  ์žฌ์ •์˜ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค.

public class Super {
	public Super() {
		overrideMe();
	}

	public void overrideMe() { ... }
}

public final class Sub extends Super {
	Sub() {
		instant = Instant.now();
	}

	@Override
	public void overrideMe() {
		System.out.println(instant);
	}

	public static void main(String[] args) {
		Sub sub = new Sub();
		sub.overrideMe();
	}
}

์ด ํ”„๋กœ๊ทธ๋žจ์ด instant๋ฅผ ๋‘ ๋ฒˆ ์ถœ๋ ฅํ•˜๋ฆฌ๋ผ ๊ธฐ๋Œ€ํ–ˆ๊ฒ ์ง€๋งŒ, ์ฒซ ๋ฒˆ์งธ๋Š” null์„ ์ถœ๋ ฅํ•œ๋‹ค. ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๋Š” ํ•˜์œ„ ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๊ฐ€ ์ธ์Šคํ„ด์Šค ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ๋„ ์ „์— overrideMe๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

clone๊ณผ readObject ๋ฉ”์„œ๋“œ๋Š” ์ƒ์„ฑ์ž์™€ ๋น„์Šทํ•œ ํšจ๊ณผ๋ฅผ ๋‚ธ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์†์šฉ ํด๋ž˜์Šค์—์„œ Cloneable์ด๋‚˜ Serializable์„ ๊ตฌํ˜„ํ• ์ง€ ์ •ํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ์ด๋“ค์„ ๊ตฌํ˜„ํ•  ๋•Œ ๋”ฐ๋ฅด๋Š” ์ œ์•ฝ๋„ ์ƒ์„ฑ์ž์™€ ๋น„์Šทํ•˜๋‹ค๋Š” ์ ์— ์ฃผ์˜ํ•˜์ž. ์ฆ‰, clone๊ณผ readObject ๋ชจ๋‘ ์ง์ ‘์ ์œผ๋กœ๋“  ๊ฐ„์ ‘์ ์œผ๋กœ๋“  ์žฌ์ •์˜ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ, Serializable์„ ๊ตฌํ˜„ํ•œ ์ƒ์†์šฉ ํด๋ž˜์Šค๊ฐ€ readResolve๋‚˜ writeReplace ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ–๋Š”๋‹ค๋ฉด ์ด ๋ฉ”์„œ๋“œ๋“ค์€ private์ด ์•„๋‹Œ protected๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค. private์œผ๋กœ ์„ ์–ธํ•œ๋‹ค๋ฉด ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๋ฌด์‹œ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด ์—ญ์‹œ ์ƒ์†์„ ํ—ˆ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ํด๋ž˜์Šค API๋กœ ๊ณต๊ฐœํ•˜๋Š” ์˜ˆ ์ค‘ ํ•˜๋‚˜๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๊ทธ ์™ธ์˜ ์ผ๋ฐ˜์ ์ธ ๊ตฌ์ฒด ํด๋ž˜์Šค๋Š” ์–ด๋–จ๊นŒ?

์ „ํ†ต์ ์œผ๋กœ ์ด๋Ÿฐ ํด๋ž˜์Šค๋Š” final๋„ ์•„๋‹ˆ๊ณ  ์ƒ์†์šฉ์œผ๋กœ ์„ค๊ณ„๋˜๊ฑฐ๋‚˜ ๋ฌธ์„œํ™”๋˜์ง€๋„ ์•Š์•˜๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ƒ์†์šฉ์œผ๋กœ ์„ค๊ณ„ํ•˜์ง€ ์•Š์€ ํด๋ž˜์Šค๋Š” ์ƒ์†์„ ๊ธˆ์ง€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ƒ์†์„ ๊ธˆ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํด๋ž˜์Šค๋ฅผ final๋กœ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋˜๋Š” ๋ชจ๋“  ์ƒ์„ฑ์ž๋ฅผ private์ด๋‚˜ package-private์œผ๋กœ ์„ ์–ธํ•˜๊ณ  public ์ •์  ํŒฉํ„ฐ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๊ตฌ์ฒด ํด๋ž˜์Šค๊ฐ€ ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ ์ƒ์†์„ ๊ธˆ์ง€ํ•˜๋ฉด ์‚ฌ์šฉํ•˜๊ธฐ์— ์ƒ๋‹นํžˆ ๋ถˆํŽธํ•ด์ง„๋‹ค. ์ด๋Ÿฐ ํด๋ž˜์Šค๋ผ๋„ ์ƒ์†์„ ๊ผญ ํ—ˆ์šฉ ํ•ด์•ผ๊ฒ ๋‹ค๋ฉด ํ•ฉ๋‹นํ•œ ๋ฐฉ๋ฒ•์ด ํ•˜๋‚˜ ์žˆ๋‹ค. ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ๋Š” ์žฌ์ •์˜ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค๊ณ  ์ด ์‚ฌ์‹ค์„ ๋ฌธ์„œ๋กœ ๋‚จ๊ธฐ๋Š” ๊ฒƒ์ด๋‹ค. ์žฌ์ •์˜ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ž๊ธฐ ์‚ฌ์šฉ ์ฝ”๋“œ๋ฅผ ์™„๋ฒฝํžˆ ์ œ๊ฑฐํ•˜๋ผ๋Š” ๋ง์ด๋‹ค.

ํด๋ž˜์Šค์˜ ๋™์ž‘์„ ์œ ์ง€ํ•˜๋ฉด์„œ ์žฌ์ •์˜ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๊ณ„์ ์ธ ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•œ๋‹ค. ๋จผ์ € ๊ฐ๊ฐ์˜ ์žฌ์ •์˜ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ๋Š” ์ž์‹ ์˜ ๋ณธ๋ฌธ ์ฝ”๋“œ๋ฅผ private '๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ'๋กœ ์˜ฎ๊ธฐ๊ณ  ์ด ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ์ˆ˜์ •ํ•œ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์žฌ์ •์˜ ๊ฐ€๋Šฅ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค๋„ ๋ชจ๋‘ ์ด ๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜๋„๋ก ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค.

๋„์šฐ๋ฏธ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•œ ์‚ฌ๋ก€๋Š” ์–ด๋–ค๊ฒŒ ์žˆ์„๊นŒ?

์ •๋ฆฌ

์ƒ์†์šฉ ํด๋ž˜์Šค๋ฅผ ์„ค๊ณ„ ํ•˜๊ธฐ๋ž€ ๊ฒฐ์ฝ” ๋งŒ๋งŒ์น˜ ์•Š๋‹ค. ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์Šค์Šค๋กœ๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€(์ž๊ธฐ์‚ฌ์šฉ ํŒจํ„ด) ๋ชจ๋‘ ๋ฌธ์„œ๋กœ ๋‚จ๊ฒจ์•ผ ํ•˜๋ฉฐ, ์ผ๋‹จ ๋ฌธ์„œํ™”ํ•œ ๊ฒƒ์€ ๊ทธ ํด๋ž˜์Šค๊ฐ€ ์“ฐ์ด๋Š” ํ•œ ๋ฐ˜๋“œ์‹œ ์ง€์ผœ์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ์ง€ ์•Š์œผ๋ฉด ๊ทธ ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ฐฉ์‹์„ ๋ฏฟ๊ณ  ํ™œ์šฉํ•˜๋˜ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ์˜ค๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋ฅธ ์ด๊ฐ€ ํšจ์œจ ์ข‹์€ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ์ผ๋ถ€ ๋ฉ”์„œ๋“œ๋ฅผ protected๋กœ ์ œ๊ณตํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•ด์•ผ ํ•  ๋ช…ํ™•ํ•œ ์ด์œ ๊ฐ€ ๋– ์˜ค๋ฅด์ง€ ์•Š์œผ๋ฉด ์ƒ์†์„ ๊ธˆ์ง€ํ•˜๋Š” ํŽธ์ด ๋‚˜์„ ๊ฒƒ์ด๋‹ค. ์ƒ์†์„ ๊ธˆ์ง€ํ•˜๋ ค๋ฉด ํด๋ž˜์Šค๋ฅผ final๋กœ ์„ ์–ธํ•˜๊ฑฐ๋‚˜ ์ƒ์„ฑ์ž ๋ชจ๋‘๋ฅผ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.