Finalizer Rules
이 룰셋은 finalizer에 관한 룰을 포함하고 있다.
Effective Java에서는 여러가지 이유로 finalizer의 사용을 경고하고 있다. 정말 꼭 필요할 경우에만 사용하자. Java는 C가 아니다. 소멸자로 오인은 금물
EmptyFinalizer
만약 finalize() 메소드가 비어있다면, 이 메소드는 존재할 필요가 없다.
public class Foo { //비어있는 finalize() 존재 이유가 없다. protected void finalize() {} }
FinalizeOnlyCallsSuperFinalize
만약 구현된 finalize() 메소드는 supert.finalize() 호출과 함께 다른 작업들을 해야한다.
public class Foo { protected void finalize() { //이 클래스에 맞는 다른 작업을 수행해야한다. super.finalize(); } }
FinalizeOverloaded
finalized() 메소드는 전달 인자가 없어야 한다. finalize()를 overload하는 것은 혼란스럽고 버그를 유발할 가능성이 있다. 또한 overload된 메소드는 VM이 호출할 수 없다.
public class Foo { //이 overload된 메소드는 혼란스럽고 버그를 유발하며 //VM으로부터 호출될 수 없다. protected void finalize(int a) { } }
FinalizeDoesNotCallSuperFinalize
finalize() 메소드 구현시 마지막 기능은 super.finalize()를 호출하는 것이어야 한다.
public class Foo { protected void finalize() { something(); //super.finalize()를 호출하는 것을 까먹지 말자 } }
FinalizeShouldBeProtected
finalize() 메소드를 오버라이드 할 경우 꼭 protected로 접근제한을 해야 한다. 그렇지 않고 public으로 설정할 경우 다른 클래스에서 호출할 가능성이 있다.
public class Foo { //다른 클래스에서 호출할 가능성이 있다. public void finalize() { // do something } //안전하게 해당 클래스 또는 자식 클래스에서만 호출할 수 있다. protected void finalize() { // do something } }
AvoidCallingFinalize
객체의 finalize() 메소드는 GC (garbage collector)에 의하여 해당 객체에 대한 더 이상의 참조가 없을 호출이 결정된다. 그러므로 직접적으로 구현된 객체의 finalize()를 호출하는 것은 피하자.
public class Foo { void foo() { Bar b = new Bar(); //finalize는 GC가 알아서 호출한다. 임의로 호출은 최대한 피하자 b.finalize(); } }
해당 URL: http://pmd.sourceforge.net/pmd-4.2.6/rules/finalizers.html