๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Java

immutability(๋ถˆ๋ณ€์„ฑ)

by seonggu 2024. 3. 7.

๐Ÿ”ด ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ(Immutability)๋ž€?
๊ฐ์ฒด๊ฐ€ immutable ํ•˜๋‹ค๋Š” ๊ฒƒ์€ ๊ฐ์ฒด๊ฐ€ ์ตœ์ดˆ ์ƒ์„ฑ๋œ ์‹œ์  ์ดํ›„ ์ƒํƒœ ๊ฐ’์ด ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.
๊ฐ์ฒด๋ฅผ ์ฒ˜์Œ ๋งŒ๋“ค์—ˆ์„ ๋Œ€์˜ ์†์„ฑ์„ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์‚ฌ๋ผ์งˆ ๋•Œ๊นŒ์ง€ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•œ๋‹ค๋Š” ๊ฒƒ.



๐Ÿ”ด ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ์ด ์™œ ์ค‘์š”ํ• ๊นŒ? ์–ด๋–ค ์žฅ๋‹จ์ ์ด ์žˆ์„๊นŒ?
์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”(Effective Java)์—์„œ๋Š” ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์žˆ์ง€ ์•Š์€ ์ด์ƒ ํด๋ž˜์Šค๋Š” immutableํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.


Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible.


์—ฌ๋Ÿฌ๊ฐ€์ง€ ์žฅ์ ์ด ์กด์žฌํ•˜๋Š”๋ฐ
์ผ๋‹จ ๊ฐ์ฒด๋ฅผ immutableํ•˜๊ฒŒ ์ƒ์„ฑํ•œ๋‹ค๋ฉด ์ƒ์„ฑ ์‹œ์  ์ดํ›„ ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ์‹คํ–‰ ์ค‘์ธ ์“ฐ๋ ˆ๋“œ ๊ฐ„์˜ ์„œ๋กœ ๊ฐ„์„ญ์— ์˜ํ•ด ์ƒ๊ธธ์ˆ˜ ์žˆ๋Š” ๋™๊ธฐํ™”(synchronization) ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ฑฑ์ •์„ ์•ˆ ํ•ด๋„ ๋˜๊ฒŒ ํ•ด์ค€๋‹ค.
์œ„์™€ ๊ฐ™์€ ๊ฒƒ์„ Thread safeํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.


์ด๋Ÿฐ ์ด์œ  ๋•Œ๋ฌธ์— ๋™์‹œ์„ฑ์ด ์ค‘์š”ํ•œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ํŠนํžˆ ์œ ์šฉํ•˜๋‹ค.
๋ถˆ๋ณ€ ๊ฐ์ฒด๋“ค์„ ํ™œ์šฉํ•˜๋ฉด side-effect์— ๋Œ€ํ•œ ๊ฑฑ์ •์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„ค๊ณ„, ๊ตฌํ˜„, ๋ฐ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ํŽธ๋ฆฌํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฐ„ exception์ด ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์‚ฌ์šฉํ–ˆ๋˜ ๊ฐ์ฒด๋“ค์˜ ์ƒํƒœ๊ฐ’์€ ๋ณ€ํ•จ์ด ์—†๊ณ , ์ด๋Ÿฐ ์žฅ์  ๋Œ€๋ฌธ์— ์บ์‹œ ํ•ด๋‘๊ณ  ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํšจ์œจ์„ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.


ํ•˜์ง€๋งŒ, Immutability๋ฅผ ๋ณด์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ๋‹จ์ ๋„ ์กด์žฌํ•œ๋‹ค.

๋ชจ๋“  ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด, ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผํ•œ๋‹ค๋Š” ๋‹จ์ ๋„ ์žˆ๊ณ , ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŽ์ด ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑฑ์ •๋„ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ Oracle์—์„œ๋Š” ๊ฐ์ฒด ์ƒ์„ฑ ๋น„์šฉ์— ๋Œ€ํ•œ ์˜ํ–ฅ์€ ์ข…์ข… ๊ณผ๋Œ€ ํ‰๊ฐ€๋˜๋ฉฐ, ๋ถˆ๋ฉด ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•  ๋•Œ์˜ ์ด์ ๋“ค์ด ์ด๋Ÿฐ ๋‹จ์ ์„ ์ƒ์‡„ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.




๐Ÿ”ด ๊ฐ์ฒด๋ฅผ Immutableํ•˜๊ฒŒ ์“ฐ๋Š” ๋ฐฉ๋ฒ•?

๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๊ฒŒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ผ๊นŒ?


1) setter ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์ง€ ๋ง์ž
๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” setter ๋ฉ”์„œ๋“œ๋ฅผ ์•„์˜ˆ ๋งŒ๋“ค์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
IDE๋กœ ๊ฐœ๋ฐœํ•˜๋‹ค๋ณด๋ฉด getter์™€ setter ๋ฉ”์„œ๋“œ๋ฅผ ๋ชจ๋“  ํด๋ž˜์Šค์— ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ,
์ƒํƒœ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ํด๋ž˜์Šค์— setter ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ์ƒํƒœ ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ํ•„์š”๊ฐ€ ์—†๋Š”๋ฐ getter ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฑด ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ผด์ด ๋œ๋‹ค.

์š”์•ฝ : ์ƒํƒœ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด setter ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.



2) final class๋กœ ์„ ์–ธ
ํด๋ž˜์Šค ์ž์ฒด๋ฅผ final๋กœ ์„ ์–ธํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ์ƒ์† ๋ฐ›๋Š” ๊ฒŒ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ถ€๋ชจ ํด๋ž˜์Šค์— ์„ ์–ธ๋˜์–ด ์žˆ๋Š” ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ•˜์ง€๋งŒ ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ ๋ฟ์ด์ง€ ํ•ด๋‹น ํด๋ž˜์Šค ๊ฐ์ฒด๋“ค์ด immutability๋ฅผ ๋ณด์žฅํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.
์„ ์–ธํ•œ final class 1๋ฒˆ setter ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ setter๋ฅผ ์‚ฌ์šฉํ•œ ์ƒํƒœ๊ฐ’ ์ˆ˜์ •์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.



3) ๋ชจ๋“  mutable ํ•„๋“œ๋ฅผ final๋กœ ์„ ์–ธ
java์—์„œ ๋ณ€์ˆ˜๋ฅผ final๋กœ ์„ ์–ธํ•˜๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ๋•Œ ํ• ๋‹น๋œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.
์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๊ฐ€ primitive type์ด๋ผ๋ฉด final๋กœ ์„ ์–ธํ•˜์—ฌ ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๊ฐ€ ํŠน์ • ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ฐธ์กฐ ๋ณ€์ˆ˜๋ผ๋ฉด, ์ฐธ์กฐ ๋Œ€์ƒ์ด ๋ฐ”๋€” ์ˆ˜ ์—†๋‹ค๋Š” ๋œป์ผ ๋ฟ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด ์ž์ฒด์˜ ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜๋Š” ์—†๋‹ค.

์ด๋Ÿฐ, ๊ฒฝ์šฐ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด ๋˜ํ•œ immutableํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ์ฒ˜๋ฆฌํ•ด์ฃผ์ž.



4) ๋ชจ๋“  ํ•„๋“œ์˜ ์ ‘๊ทผ์ œ์–ด์ž๋ฅผ private๋กœ ์„ ์–ธ
ํด๋ž˜์Šค์˜ ๋ชจ๋“  ํ•„๋“œ๋ฅผ private์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋งŒ ํ•ด๋‹น ํ•„๋“œ์— ๋Œ€ํ•œ ์ ‘๊ทผ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.
ํด๋ž˜์Šค์— setter ๋ฉ”์„œ๋“œ๊ฐ€ ์—†๋‹ค๋ฉด private์œผ๋กœ ์„ ์–ธํ•ด ์™ธ๋ถ€ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ ‘๊ทผ์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.



5) ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐํ™”๋˜๋Š” ํ•„๋“œ๋“ค์€ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ†ตํ•ด ์ฐธ์กฐ ๋Œ€์ƒ ์žฌํ• ๋‹น
์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐํ™” ๋˜๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋“ค์ด reference ๋ณ€์ˆ˜๋ผ๋ฉด ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ†ตํ•ด ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๊ฐ’์ด ๋ณ€ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.



6) getter๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์„ ๋ฐ˜ํ™˜
getter ๋ฉ”์„œ๋“œ๋Š” ์‹ค์ œ ๊ฐ์ฒด์— ๋Œ€ํ•œ reference๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹  ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•œ ๊ฐ์ฒด์— ๋Œ€ํ•œ reference๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ, ๋ฐ˜ํ™˜๋ฐ›์€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์‹ค์ˆ˜๋กœ๋ผ๋„ ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๊ฑด๋“œ๋ฆด ์ผ์ด ์—†๊ฒŒ๋” ๋งŒ๋“ค์ž.




์ฐธ๊ณ ์ž๋ฃŒ :
https://www.baeldung.com/java-immutable-object
https://seunghyunson.tistory.com/24