이펙티브 자바 아이템8

한주영·2023년 10월 5일
0

이펙티브자바

목록 보기
7/33

finalizer와 cleaner사용을 피하라

1.finalizer는 예측할수없고 상황에따라 위험할수있어 불필요하다

2.cleaner는 finalizer보다는 덜 위험하지만 예측할수없고 느리고 일반적으불필요

3.finalizer와 cleaner는 제때실행되어야하는 작업은 절대 할수없다.

4.상태를 영구적으로 수정하는 작업에서는 finalizer와 cleaner에 의존하면 안된다.

5.finalizer와 cleaner는 성능 문제도 동반

6.finalizer를 사용한 클래스는 finalizer공격에 노출되어 심각한 보안 문제를 일으킬수도있다.
1)객체생성을 막으려면 생성자에서 예외를 던지는것만으로도 충분하지만 finalizer가 있다면 그렇지도 않다

7.final이 아닌 클래스를 finalizer공격으로부터 방어하려면 아무일도 하지않는 finalizer메서드를 만들고 final로 선언

8.finalizer와 cleaner의대안
1) AutoCloseable을 구현해주고 클라이언트에서 인스턴스를 다쓰고나면
close메서드를 호출

9.finalizer와 cleaner의 쓰임새
1)자원의 소유자가 close메서드를 호출하지 않은것에 대비한 안전망 역할
2)네이티브 피어와 연결된 객체에서 쓰인다
-네이티브 피어란 일반 자바객체가 아니기때문에 가비지 컬렉터는 그 존재를 알지 못한다.

public class Room {
  
  private static final Cleaner cleaner = Cleaner.create();
  
  //청소가 필요한 자원, 절대 Room을 참조해서는 안된다!
  
  private static class State implements Runnable{
      
      State(int numJunkpiles){
          this.numJunkpiles=numJunkpiles;
      }


      @Override
      public void run() {
          System.out.println("방 청소");
          numJunkpiles=0;
      }
      
      private final State state;
      
      private final Cleaner.Cleanable cleanable;
      
      public Room(int numJunkPlies){
          
          state=new State(numJunkPlies);
          cleanable=cleaner.register(this,state);
      }
      
      @Override
      public void close(){
          cleanable.clean();
      }
  }
}

1)State는 방을청소할때 수거할 자원들을 담고있다
2)State는 Runnable을 구현하고 그안의 run메서드는 cleanble에의해 한번만 호출

Room의 cleaner는 단지안전망으로만 쓰였다
잘짜여진 클라이언트 코드

public class Adult {

    public static void main(String[] args) {
        try(Room myRoom= new Room(7)){
            System.out.println("안녕~");
        }
    }
}
public class Teenager {

    public static void main(String[] args) {
        
        new Room(99);
        System.out.println("아무렵");
    }
}
profile
백엔드개발자가 되고싶은 코린이:)

0개의 댓글