πŸ“– Effective java item 28 - λ°°μ—΄λ³΄λ‹€λŠ” 리슀트λ₯Ό μ‚¬μš©ν•˜λΌ


μš°ν…Œμ½” Level 1 둜또 λ―Έμ…˜μ—μ„œ β€œλ°°μ—΄ λŒ€μ‹  ArrayListλ₯Ό μ‚¬μš©ν•œλ‹€.”가 μš”κ΅¬μ‚¬ν•­μ— λ“€μ–΄μžˆμ—ˆλ‹€.
μ™œ λ°°μ—΄λŒ€μ‹  ArrayListλ₯Ό μ‚¬μš©ν•˜λΌλŠ” κ²ƒμΌκΉŒ?
μ°Ύμ•„λ³΄λ‹ˆ μ΄νŽ™ν‹°λΈŒ μžλ°”μ—μ„œλ„ κ·Έ λ‚΄μš©μ΄ λ‚˜μ™€ μžˆμ–΄μ„œ 슀슀둜의 λ¬ΌμŒμ— λ‹΅ν•˜λŠ” λ‚΄μš©μ„ μ •λ¦¬ν•˜λ € ν•œλ‹€.

Array(λ°°μ—΄) vs ArrayList(리슀트)

듀어가기에 μ•žμ„œ μ΄νŽ™ν‹°λΈŒ μžλ°”λ₯Ό 보기 μ „ Arrayκ³Ό ArrayList의 차이점을 κ°„λ‹¨νžˆ 적어본닀.

Array(λ°°μ—΄)

  • μ‚¬μ΄μ¦ˆκ°€ 정적인 데이터 ꡬ쑰이닀. 일단 μƒμ„±λ˜λ©΄ 크기λ₯Ό λ³€κ²½ν•  수 μ—†λ‹€.
  • μ›μ‹œ νƒ€μž…κ³Ό 객체 λͺ¨λ‘ μ›μ†Œλ‘œ 포함할 수 μžˆλ‹€.
  • for λ˜λŠ” for-each 루프λ₯Ό ν†΅ν•΄μ„œ λ°˜λ³΅λœλ‹€.
  • 길이에 λŒ€ν•΄ length λ³€μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€.
  • Generic(μ œλ„€λ¦­)을 μ‚¬μš© ν•  수 μ—†λ‹€.
  • μ›μ†Œλ₯Ό ν• λ‹Ήν•˜κΈ° μœ„ν•΄ ν• λ‹Ή μ—°μ‚°μž=λ₯Ό μ‚¬μš©ν•œλ‹€.

ArrayList(리슀트)

  • μ‚¬μ΄μ¦ˆκ°€ 동적인 데이터 ꡬ쑰이닀. μš©λŸ‰μ„ μ΄ˆκ³Όν•˜λŠ” μš”μ†Œλ₯Ό μΆ”κ°€ν•˜λ©΄ 크기가 μžλ™μœΌλ‘œ μ¦κ°€ν•œλ‹€.
  • 객체 μ›μ†Œλ§Œ 포함할 수 μžˆλ‹€.
  • μš”μ†Œλ₯Ό λ°˜λ³΅ν•˜λŠ” iteratorsλ₯Ό μ œκ³΅ν•œλ‹€.
  • 길이에 λŒ€ν•΄ size() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.
  • Generic(μ œλ„€λ¦­)을 μ§€μ›ν•œλ‹€.
  • μ›μ†Œλ₯Ό ν• λ‹Ήν•˜κΈ° μœ„ν•΄ add() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.
  • Collectionsκ°€ μ œκ³΅ν•˜λŠ” λ‹€μ–‘ν•œ λ©”μ†Œλ“œλ“€μ„ μ‚¬μš©ν•  수 μžˆλ‹€.

Effective Java item 28

λ°°μ—΄κ³Ό μ œλ„€λ¦­ νƒ€μž…μ˜ 차이

배열은 곡변이닀.

Subκ°€ Super의 ν•˜μœ„ νƒ€μž…μ΄λΌλ©΄ λ°°μ—΄ Sub[]λŠ” Super[]의 ν•˜μœ„ νƒ€μž…μ΄ λœλ‹€.
즉 ν•¨κ»˜ λ³€ν•œλ‹€λŠ” 말이닀.
ν•˜μ§€λ§Œ μ œλ„€λ¦­μ€ λΆˆκ³΅λ³€μœΌλ‘œ μ„œλ‘œ λ‹€λ₯Έ νƒ€μž… Type1, Type2κ°€ μžˆμ„ λ•Œ,
List<Type1>은 List<Type2>의 ν•˜μœ„ νƒ€μž…λ„, μƒμœ„ νƒ€μž…λ„ μ•„λ‹ˆλ‹€.

곡변이 μ™œ λ¬Έμ œκ°€ λ˜μ§€?

μ•„λž˜ μ½”λ“œλŠ” 문법상 ν—ˆμš©μ€ λ˜μ§€λ§Œ λŸ°νƒ€μž„μ— μ‹€νŒ¨ν•œλ‹€.

Object[] objectArray = new Long[1];
/* ArrayStoreException λ°œμƒ */
objectArray[0] = "νƒ€μž…μ΄ 달라 넣을 수 μ—†μŒ";

또 μ•„λž˜ μ½”λ“œλŠ” 컴파일 였λ₯˜λ₯Ό μΌμœΌν‚¨λ‹€.

List<Object> objectList = new ArrayList<Long>();
objectList.add("νƒ€μž…μ΄ 달라 넣을 수 μ—†μŒ");

두 μ½”λ“œ λͺ¨λ‘μ—μ„œ Long용 μ €μž₯μ†Œμ— String을 넣을 수 μ—†λ‹€.
배열은 이λ₯Ό λŸ°νƒ€μž„μ— μ•Œκ²Œ λ˜μ§€λ§Œ λ¦¬μŠ€νŠΈλŠ” 컴파일 λ•Œ λ°”λ‘œ μ•Œ 수 μžˆλ‹€.

배열은 μ‹€μ²΄ν™”λœλ‹€.

배열은 λŸ°νƒ€μž„μ—λ„ μžμ‹ μ΄ λ‹΄κΈ°λ‘œ ν•œ μ›μ†Œμ˜ νƒ€μž…μ„ μΈμ§€ν•˜κ³  ν™•μΈν•œλ‹€.
λ•Œλ¬Έμ— Long용 μ €μž₯μ†Œμ— String을 λ„£μœΌλ € ν•˜λ©΄ ArrayStoreException을 λ°œμƒμ‹œν‚¨λ‹€.

ν•˜μ§€λ§Œ μ œλ„€λ¦­μ€ νƒ€μž… 정보가 λŸ°νƒ€μž„μ—λŠ” μ†Œκ±°λœλ‹€.
μ΄λŠ” μ›μ†Œμ˜ νƒ€μž…μ„ 컴파일 νƒ€μž„μ—λ§Œ κ²€μ‚¬ν•˜λ©° λŸ°νƒ€μž„μ—λŠ” μ•Œ 수 μ—†λ‹€λŠ” 것이닀.
μ—¬κΈ°μ„œ νƒ€μž… μ •λ³΄μ˜ μ†Œκ±°λΌ 함은 μ œλ„€λ¦­μ΄ μ§€μ›λ˜κΈ° μ „
λ ˆκ±°μ‹œ μ½”λ“œμ™€ μ œλ„€λ¦­ νƒ€μž…μ„ ν•¨κ»˜ μ‚¬μš©ν•  수 있게 ν•΄μ€€λ‹€.

μ œλ„€λ¦­ 배열을 λ§Œλ“€μ§€ λͺ»ν•˜κ²Œ ν•œ 이유?

κ·Έ μ΄μœ λŠ” νƒ€μž… μ•ˆμ „ν•˜μ§€ μ•ŠκΈ° 떄문이닀. μ œλ„€λ¦­ 배열을 ν—ˆμš©ν•œλ‹€λ©΄ μ»΄νŒŒμΌλŸ¬κ°€ μžλ™ μƒμ„±ν•œ ν˜•λ³€ν™˜ μ½”λ“œμ—μ„œ λŸ°νƒ€μž„μ— ClassCastException이
λ°œμƒν•  수 μžˆλŠ”λ°, μ΄λŠ” λŸ°νƒ€μž„μ— 이 μ˜ˆμ™Έκ°€ λ°œμƒν•˜λŠ” 일을 λ§‰κ² λ‹€λŠ” μ œλ„€λ¦­ νƒ€μž… μ‹œμŠ€ν…œ 취지에 λ²—μ–΄λ‚œλ‹€.

List<String>[] stringLists = new List<String>[1]; // (1) 
List<Integer> intList = List.of(42);              // (2)
Object[] objects = stringLists;                   // (3)
objects[0] = intList;                             // (4)
String s = stringLists[0].get(0);                 // (5)

λ§Œμ•½ (1)이 ν—ˆμš©λœλ‹€λ©΄ (2)λŠ” μ›μ†Œκ°€ ν•˜λ‚˜μΈ List<Integer>λ₯Ό μƒμ„±ν•œλ‹€.
(3)은 (1)μ—μ„œ μƒμ„±ν•œ List<String>의 배열을 Object 배열에 ν• λ‹Ήν•œλ‹€.
배열은 κ³΅λ³€μ΄λ‹ˆ 아무 λ¬Έμ œκ°€ μ—†λ‹€. (4) λ²ˆμ€ (2)μ—μ„œ μƒμ„±ν•œ List<Integer>의 μΈμŠ€ν„΄μŠ€λ₯Ό Object λ°°μ—΄μ˜ 첫 μ›μ†Œλ‘œ μ €μž₯ν•œλ‹€.
μ œλ„€λ¦­μ€ λŸ°νƒ€μž„ μ‹œμ μ—μ„œ νƒ€μž… 정보λ₯Ό μ†Œκ±°ν•˜λ‹ˆ List<Integer>은 Listκ°€ 되고
List<Integer>[]λŠ” List[]κ°€ λœλ‹€.
λ”°λΌμ„œ (4)μ—μ„œλ„ ArrayStoreException이 λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.
(5)μ—μ„œλŠ” List<String> μΈμŠ€ν„΄μŠ€λ§Œ λ‹΄κ² λ‹€κ³  μ„ μ–Έν•œ stringLists λ°°μ—΄μ—λŠ”
List<Integer> μΈμŠ€ν„΄μŠ€κ°€ μ €μž₯돼 μžˆλ‹€.
(5)λŠ” 이 λ°°μ—΄μ˜ 처음 λ¦¬μŠ€νŠΈμ—μ„œ 첫 μ›μ†Œλ₯Ό κΊΌλ‚΄λ € ν•˜λŠ”λ° μ»΄νŒŒμΌλŸ¬λŠ” κΊΌλ‚Έ μ›μ†Œλ₯Ό μžλ™μœΌλ‘œ String으둜
ν˜•λ³€ν™˜ ν•˜λŠ”λ°, 이 μ›μ†ŒλŠ” Integerμ΄λ‹ˆ λŸ°νƒ€μž„μ— ClassCastExceptiondl qkftodgksek.

이λ₯Ό 막기 μœ„ν•΄μ„œ μ œλ„€λ¦­ λ°°μ—΄ 생성을 막도둝 (1)μ—μ„œ 컴파일 였λ₯˜λ₯Ό λ‚΄μ•Ό ν•œλ‹€.

싀체화 λΆˆκ°€ νƒ€μž…

E, List<E>, List<String> 같은 νƒ€μž…μ„ 싀체화 λΆˆκ°€ νƒ€μž…μ΄λΌ ν•œλ‹€.
μ œλ„€λ¦­μ€ νƒ€μž… μ†Œκ±°λ‘œ 인해 μ‹€μ²΄ν™”λ˜μ§€ μ•Šμ•„μ„œ λŸ°νƒ€μž„μ—λŠ” μ»΄νŒŒμΌνƒ€μž„λ³΄λ‹€ νƒ€μž… 정보λ₯Ό 적게 κ°€μ§€λŠ” νƒ€μž…μ„ λœ»ν•œλ‹€.
(λ§€κ°œλ³€μˆ˜ν™” νƒ€μž… κ°€μš΄λ° 싀체화 될 수 μžˆλŠ” νƒ€μž…μ€ λΉ„ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ νƒ€μž… 뿐이닀.)

정리

λ°°μ—΄κ³Ό μ œλ„€λ¦­μ—λŠ” 맀우 λ‹€λ₯Έ νƒ€μž… κ·œμΉ™μ΄ μ μš©λ˜μ–΄μ„œ λ‘˜μ„ μ„žμ–΄ μ“°κΈ°λž€ 쉽지 μ•Šλ‹€.
배열은 곡변, μ œλ„€λ¦­μ€ λΆˆκ³΅λ³€μ΄λ‹€.
이 말은 배열은 λŸ°νƒ€μž„ νƒ€μž…μ— μ•ˆμ „ν•˜μ§€λ§Œ 컴파일 νƒ€μž„μ— μ•ˆμ „ν•˜μ§€ λͺ»ν•˜λ‹€.
μ œλ„€λ¦­μ€ κ·Έ λ°˜λŒ€μ΄λ‹€.

λ‹¨μˆœνžˆ μ‚¬μ΄μ¦ˆκ°€ 정적인지 λ™μ μΈμ§€μ˜ 차이 뿐만 μ•„λ‹ˆλΌ λ°°μ—΄κ³Ό λ¦¬μŠ€νŠΈμ—λŠ” μ΄λ ‡κ²Œ λ§Žμ€
차이점이 μ‘΄μž¬ν•˜κ³  μžˆμ—ˆλ‹€.

λ§Œμ•½ λ‘˜μ„ μ„žμ–΄ μ“°λ‹€κ°€ 컴파일 였λ₯˜λ‚˜ κ²½κ³ λ₯Ό λ§Œλ‚˜λ©΄, λ¨Όμ € 배열을 리슀트둜 λŒ€μ²˜ν•˜μž!

참고 자료