종료자는 예측 불가능하며 대체로 위험하고 일반적으로 불필요하다.
종료자의 단점 및 주의할 점
1.C++의 소멸자와는 다른개념이다. 종료자는 즉시 실행되리라는 보장이 전혀 없다. 그러므로 긴급한 작업을 종료자 안에서 처리하면 안된다. 종료자의 실행시점은 GC 알고리즘에 좌우되는데 이는 JVM 구현마다 크게 다르다. 또한 클래스에 종료자를 붙여놓으면 객체 메모리 반환이 지연될 수 있다.
2.종료자는 즉시 실행되는것을 보장하지 않기때문에 지속성이 보장되어야 하는 중요상태정보는 종료자로 갱신하면 안된다.
3.종료자를 사용하면 프로그램 성능이 떨어진다.즉 종료자를 사용하지 말고 명시적인 종료메서드를 하나 정의하고 이를 호출해라! 또한 종료여부를 객체안에 private로 보관하라
명시적 종료의 예로 OutputStream, InputStream의 close 메서드가 있다. 주로 finally안에서 호출하여 예외가 발생해도 실행될 수 있도록 한다,
종료자의 쓰임
1.명시적 종료메서드 호출을 잊을 경우에 대비하는 안전망으로의 역할
2.네이티브 피어와 연결된 객체를 다룰 때 - 일반 객체가 아니므로 GC가 알 수 없다.
하위클래스에서의 종료자 생성
하위클래스에서 종료자를 오버라이딩 하면 상위클래스의 종료자를 호출 해 줘야 한다. 하지만 이를 잊어먹고 하지 않는경우 이로인한 문제가 발생한다.
이를 방지하기 위해 익명클래스 안에 종료자를 정의하여 사용하는 방법이 좋다. 이를 종료 보호자(finalizer guardian)라 함.
종료보호자에 대한 설명: 익명클래스로 finalize를 오버라이딩 하면 해당 스코프를 벗어나면 GC가 finalize를 호출하게 되어 상속받은 하위클래스가 super.finalize를 호출하지 않아도 된다.
https://stackoverflow.com/questions/6872857/how-does-a-finalizer-guardian-work-in-java
즉 네이티브 자원을 종료시키려는것이 아니라면 종료자는 사용하지 말고 종료자를 불가피하게 사용해야할 경우에는 super.finalize()를 호출해라.