[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item21. μΈν„°νŽ˜μ΄μŠ€λŠ” κ΅¬ν˜„ν•˜λŠ” μͺ½μ„ κ³ λ €ν•΄ μ„€κ³„ν•˜λΌ.

2023. 3. 7. 10:59ㆍJAVA/Effective JAVA

728x90

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item21. μΈν„°νŽ˜μ΄μŠ€λŠ” κ΅¬ν˜„ν•˜λŠ” μͺ½μ„ κ³ λ €ν•΄ μ„€κ³„ν•˜λΌ. 

 

μžλ°”8 μ „μ—λŠ” μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•  방법이 μ—†μ—ˆλŠ”λ° μžλ°” 8에 μ™€μ„œ κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•  수 있게 됐닀. 

λ””ν΄νŠΈ λ©”μ„œλ“œλ‘œ μ„ μ–Έν•˜λ©΄ κ·Έ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν›„ λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•˜μ§€ μ•Šμ€ λͺ¨λ“  ν΄λž˜μŠ€μ—μ„œ λ””ν΄νŠΈ κ΅¬ν˜„μ΄ μ“°μ΄κ²Œ λœλ‹€. 

이제 μžλ°”μ—μ„œλ„ κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•  수 μžˆμ§€λ§Œ λͺ¨λ“  κΈ°μ‘΄ κ΅¬ν˜„μ²΄λ“€κ³Ό λ§€λ„λŸ½κ²Œ μ—°λ™λœλ‹€λŠ” 보μž₯은 μ—†λ‹€. 

 

 

 

- κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€μ— λ””ν΄νŠΈ λ©”μ„œλ“œ κ΅¬ν˜„μ„ μΆ”κ°€ν•˜λŠ” 것은 μœ„ν—˜ν•œ 일이닀. 

κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€μ— λ””ν΄νŠΈ λ©”μ„œλ“œ κ΅¬ν˜„μ„ μΆ”κ°€ν•˜λŠ” 것은 μœ„ν—˜ν•˜κΈ΄ν•˜λ‹€. 

μ™œλƒν•˜λ©΄ λ””ν΄νŠΈ λ©”μ„œλ“œλŠ” κ΅¬ν˜„ ν΄λž˜μŠ€μ— λŒ€ν•΄ 아무것도 λͺ¨λ₯Έ 채 ν•©μ˜ 없이 λ¬΄μž‘μ • μ‚½μž…λ˜κΈ° λ•Œλ¬Έμ΄λ‹€. 

 

μžλ°” 라이브러리의 λ””ν΄νŠΈ λ©”μ„œλ“œλŠ” μ½”λ“œ ν’ˆμ§ˆμ΄ λ†’κ³  λ²”μš©μ μ΄λΌ λŒ€λΆ€λΆ„μ˜ μƒν™©μ—μ„œ 잘 μž‘λ™ν•˜μ§€λ§Œ 생각할 수 μžˆλŠ” λͺ¨λ“  μƒν™©μ—μ„œ λΆˆλ³€μ‹μ„ ν•΄μΉ˜μ§€ μ•ŠλŠ” λ””ν΄νŠΈ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•˜κΈ°λž€ μ–΄λ €μš΄ 법이닀. 

 

 

/**
 * Removes all of the elements of this collection that satisfy the given
 * predicate.  Errors or runtime exceptions thrown during iteration or by
 * the predicate are relayed to the caller.
 *
 * @implSpec
 * The default implementation traverses all elements of the collection using
 * its {@link #iterator}.  Each matching element is removed using
 * {@link Iterator#remove()}.  If the collection's iterator does not
 * support removal then an {@code UnsupportedOperationException} will be
 * thrown on the first matching element.
 *
 * @param filter a predicate which returns {@code true} for elements to be
 *        removed
 * @return {@code true} if any elements were removed
 * @throws NullPointerException if the specified filter is null
 * @throws UnsupportedOperationException if elements cannot be removed
 *         from this collection.  Implementations may throw this exception if a
 *         matching element cannot be removed or if, in general, removal is not
 *         supported.
 * @since 1.8
 */
default boolean removeIf(Predicate<? super E> filter) {
    Objects.requireNonNull(filter);
    boolean removed = false;
    final Iterator<E> each = iterator();
    while (each.hasNext()) {
        if (filter.test(each.next())) {
            each.remove();
            removed = true;
        }
    }
    return removed;
}

μžλ°” 8 Collection μΈν„°νŽ˜μ΄μŠ€μ— μΆ”κ°€λœ removeIf λ©”μ„œλ“œλ₯Ό 예λ₯Ό λ“€μ–΄ 보면 이 λ©”μ„œλ“œλŠ” 주어진 λΆˆλ¦¬μ–Έ ν•¨μˆ˜ Predicate κ°€ trueλ₯Ό λ°˜ν™˜ν•˜λŠ” λͺ¨λ“  μ›μ†Œλ₯Ό μ œκ±°ν•œλ‹€. 

이 μ½”λ“œμ—μ„œ ν˜„μ‘΄ν•˜λŠ” λͺ¨λ“  Collection κ΅¬ν˜„μ²΄μ™€ 잘 μ–΄μšΈλ¦¬λŠ” 것은 μ•„λ‹Œλ° SynchronizedCollection이 λŒ€ν‘œμ μΈ μ˜ˆμ΄λ‹€. 

이 ν΄λž˜μŠ€λŠ” λͺ¨λ“  λ©”μ„œλ“œμ—μ„œ 주어진 락 객체둜 λ™κΈ°ν™”ν•œ ν›„ λ‚΄λΆ€ μ»¬λ ‰μ…˜ 객체에 κΈ°λŠ₯을 μœ„μž„ν•˜λŠ” 래퍼 ν΄λž˜μŠ€μ΄λ‹€. 

 

근데 이 ν΄λž˜μŠ€μ—μ„œ remveIf λ””ν΄νŠΈ κ΅¬ν˜„μ„ λ¬Όλ €λ°›κ²Œ λœλ‹€λ©΄ 예기치 λͺ»ν•œ 결과둜 μ΄μ–΄μ§ˆ 수 μžˆλ‹€..!!

removeIf의 κ΅¬ν˜„μ€ 동기화에 κ΄€ν•΄μ„œλŠ” 아무것도 λͺ¨λ₯΄κΈ° λ•Œλ¬Έμ— 락 객체λ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€. 

SynchronizedCollection μΈμŠ€ν„΄μŠ€λ₯Ό μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ κ³΅μœ ν•˜λŠ” ν™˜κ²½μ—μ„œ ν•œ μŠ€λ ˆλ“œκ°€ removeIf λ₯Ό ν˜ΈμΆœν•˜λ©΄ ConcurrentModificationException이 λ°œμƒν•˜κ±°λ‚˜ 예기치 λͺ»ν•œ 결과둜 μ΄μ–΄μ§ˆ 수 μžˆλ‹€. 

 

 

 

 

- λ””ν΄νŠΈ λ©”μ„œλ“œλŠ” μ»΄νŒŒμΌμ— μ„±κ³΅ν•˜λ”λΌλ„ κΈ°μ‘΄ κ΅¬ν˜„μ²΄μ— λŸ°νƒ€μž„ 였λ₯˜λ₯Ό μΌμœΌν‚¬ 수 μžˆλ‹€. 

public class Superclass
{
   private void hello()
   {
      System.out.println("Superclass.hello");
   }
}
public interface MakerInterface
{
   default void hello()
   {
      System.out.println("MakerInterface.hello");
   }
}
public class SubClass extends Superclass implements MakerInterface
{
   public static void main(String[] args)
   {
      SubClass subClass = new SubClass();
      subClass.hello(); 
   }
}

이 μ½”λ“œλ₯Ό 싀행해보면 λŸ°νƒ€μž„ 였λ₯˜κ°€ λ°œμƒν•œλ‹€. 

'Exception in thread "main" java.lang.IllegalAccessError: class chapter03.item21.SubClass tried to access private method chapter03.item21.Superclass.hello()V'

 

항상 ꡬ체적인 것이 더 μš°μ„ ν•˜κ²Œ λ˜μ–΄μžˆκΈ° λ•Œλ¬Έμ— ν΄λž˜μŠ€κ°€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄κΈ°λŠ”λ° 이 κ·œμΉ™?을 λ”°λΌμ„œ Subclassμ—μ„œ helloλ₯Ό ν˜ΈμΆœν•œ 것은 μΈν„°νŽ˜μ΄μŠ€μ˜ helloκ°€ μ•„λ‹ˆλΌ SuperClass의 hello이닀. 근데 SuperClass의 helloλŠ” private인데도 호좜이 λ˜λŠ” μ—λŸ¬? 버그가 있고, 

κ·Έ κ²°κ³Ό 이λ₯Ό μ‹€ν–‰ν•˜λ©΄ private λ©”μ„œλ“œμ— μ ‘κ·Όν•œλ‹€κ³  λŸ°νƒ€μž„ 였λ₯˜λ₯Ό λ‚΄λŠ” 것이닀. 

 

 

 

 

πŸ“š 정리

κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€μ— λ””ν΄νŠΈ λ©”μ„œλ“œλ‘œ μƒˆ λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•˜λŠ” 일은 κΌ­ ν•„μš”ν•œ κ²½μš°κ°€ μ•„λ‹ˆλΌλ©΄ ν”Όν•΄μ•Ό ν•œλ‹€. 

μΆ”κ°€ν•˜λ €λŠ” λ””ν΄νŠΈ λ©”μ„œλ“œκ°€ κΈ°μ‘΄ κ΅¬ν˜„μ²΄λ“€κ³Ό μΆ©λŒν•˜μ§€λŠ” μ•Šμ„μ§€ μ‹¬μ‚¬μˆ™κ³ ν•΄μ•Ό 함도 λ‹Ήμ—°ν•˜λ‹€. 

λ°˜λ©΄μ— μƒˆλ‘œμš΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“œλŠ” 경우라면 ν‘œμ€€μ μΈ λ©”μ„œλ“œ κ΅¬ν˜„μ„ μ œκ³΅ν•˜λŠ” 것은 μ•„μ£Ό μœ μš©ν•œ μˆ˜λ‹¨μ΄ 되고, μΈν„°νŽ˜μ΄μŠ€λ₯Ό 더 μ‰½κ²Œ κ΅¬ν˜„ν•΄ ν•  수 ν™œμš©ν•  수 있게 ν•΄μ€€λ‹€. 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90