finalize 사용 방지

2885 단어

고전 읽기-Effective Java 03


Java 언어 팩의 Object 클래스는 모든 클래스의 선조입니다.이 종류는 equals,hashCode,toString,clone,finalize 등 방법을 제공했다.본고는finalize 방법을 중점적으로 토론하고 나머지는 뒷글에서 속속 나타날 것이다.

finalize 방법


Java 문서는finalize 메서드에 대해 다음과 같이 설명합니다.
대상이 더 이상 접근할 수 있는 인용이 없을 때, 쓰레기 수거기는 대상을 회수하기 전에finalize 방법을 사용합니다.하위 클래스는 이 방법에서 차지하는 시스템 자원을 방출하거나 다른 정리 작업을 수행할 수 있습니다.
보통, 우리는finalize 방법으로 이미 열린 파일을 닫지만, 이것은 심각한 오류입니다. 주의하십시오.
finalize 방법의 단점은 제때에 집행될 것을 보장하지 않고 심지어는 반드시 집행될 것을 보장하지 않는다는 것이다.프로그램이 종료될 때까지 대상에 도달할 수 없는finalize 방법이 실행되지 않는 경우가 많습니다.따라서finalize에서 파일을 닫는 데 실패할 수 있습니다.
System.gc()System.runFinalization()는finalize가 집행될 기회를 늘릴 뿐이다.finalize 방법이 프로그램이 종료되기 전에 실행될 것을 보장하는 유일한 방법은 System.runFinalizersOnExitRuntime.runFinalizersOnExit이다.그러나 그것들은 치명적인 결함이 있어 이미 폐기되었다.
finalize에서 던진 이상은 무시되어 프로그램이 성공적으로 실행되었는지 알 수 없습니다.
finalize는 심각한 성능 손실을 초래할 수 있다.
따라서finalize 방법이 이렇게 많은 단점을 가지고 있음을 감안하여 우리는 대부분 사용을 피해야 한다.그러나 여전히 두 가지 합리적인 용법이 있다.

용도1: 현식 중지 방법에 맞추다


여전히 파일을 닫는 문제입니다. 정확한 방법은 일반적인 close 라고 불리며 클라이언트 프로그램에 수동으로 호출하도록 하는 것입니다.이 방안의 전형적인 예는 InputStream,OutputStream,java.sql.Connection인데 이런 종류는 상응하는 파일이나 데이터베이스 연결을 닫는 close 방법을 제공했다.
그러나 일부 믿을 수 없는 프로그래머들은 호출close 방법을 잊어버리기 때문에finalize에서 자원 유출 가능성을 낮추기 위해close 방법을 다시 검사하고 호출할 수 있다.(finalize가 신뢰할 수 없기 때문에 이 방안은 자원 유출의 가능성을 낮출 수 있을 뿐 완전히 제거할 수 없습니다.)InputStream,OutputStream,java.sql.Connection 이런 종류에서도 확실히 이렇게 했습니다. 여러분은 직접 원본을 볼 수 있습니다.

용도2: 종결 방법 수위자


만약 하위 클래스가 부모 클래스의finalize 방법을 다시 쓰려고 한다면, 우리는 아래의 방식으로 다시 쓰는 것을 추천합니다.이렇게 하면 자류의 종결 과정이 이상을 던져도 부류의finalize 방법이 실행될 수 있음을 보장할 수 있다.
@Override
protected void finalize() throws Throwable {
  try {
    //Finalize subclass state
  } finally {
    super.finalize();
  }
}

단, 만약 하위 클래스가 다시 쓰는finalize 방법에서 호출되지 않았다면, 상위 클래스의finalize 방법은 영원히 호출되지 않을 것입니다.부류의 입장에서 이런 부주의하거나 악의적인 자류를 방지하려면 종결 방법으로 수위를 할 수 있다.
종결 방법 수위자는 부류 중의 익명 내부 클래스의 실례입니다. 이 내부 클래스는finalize 방법을 덮어쓰고 부류가 필요로 하는 종결 작업을 합니다.
public class Foo {
  private final Object finalizerGuardian = new Object() {
    @Override
    protected void finalize() throws Throwable {
      //Finalize outer Foo object
    }
  };
  //...
}

현재Foo의 하위 클래스가finalize 방법을 덮어써도Foo의 종결 작업에 영향을 주지 않습니다. 왜냐하면 super.finalize()가 계속 존재하기 때문입니다.하위 클래스의 대상이 도달할 수 없을 때finalizerGuardian도 마찬가지로 도달할 수 없으며 쓰레기 수거기의 회수 대기열에 들어간다.따라서 부류의 종결 작업이 무시되지 않도록 보장할 수 있다.
저자나 문집'Effective Java'를 주목하고 최신 게시글을 가장 먼저 받습니다.

참고 자료


Java 종료 방법 사용(종료 디펜서) SamXCode What's the behaviors of fields when finalize an object?jinge Java는finalize() 메서드를 사용하지 않습니까?Ben Evans

좋은 웹페이지 즐겨찾기