내 경험에는 재정의의 단 하나의 이유가 Object.finalize()
있지만 매우 좋은 이유입니다 .
finalize()
호출을 잊어 버린 경우 알려주 는 오류 로깅 코드를 배치합니다 close()
.
정적 분석은 사소한 사용 시나리오에서만 누락을 포착 할 수 있으며 다른 답변에 언급 된 컴파일러 경고에는 사소한 작업을 수행하기 위해 실제로 사용하지 않도록 설정해야하는 간단한 뷰가 있습니다. (알거나 알고있는 다른 프로그래머보다 훨씬 많은 경고가 활성화되어 있지만 어리석은 경고는 활성화되어 있지 않습니다.)
마무리는 리소스가 방해받지 않도록하는 좋은 메커니즘 인 것처럼 보이지만 대부분의 사람들은이를 완전히 잘못된 방식으로보고 있습니다. 즉, 대체 폴백 메커니즘, "두 번째 기회"보호 수단으로 생각합니다. 그들이 잊어 버린 자원을 처분함으로써 하루. 이것은 잘못되었습니다 . 주어진 일을 수행하는 한 가지 방법 만 있어야합니다. 항상 모든 것을 닫거나 마무리는 항상 모든 것을 닫습니다. 그러나 마무리는 신뢰할 수 없으므로 마무리는 불가능합니다.
그래서, 거기에 내가 부르는이 제도입니다 필수 처리를 하고, 프로그래머가 담당하는 규정 항상 명시 적으로 모든 닫는 구현 Closeable
또는 AutoCloseable
. (.은 try-와-자원 문 여전히 명시 적 폐쇄로 계산) 물론은, 프로그래머는, 그래서 마무리가 활동하기 시작하지만,의 잊을 수 없는 경우에는 마무리 발견한다 : 마술 오른쪽 결국 일을 할 것입니다 마법의 요정 등을 것을 close()
호출되지 않은, 그것은 수행 하지(수학적 확실성으로) 그들이 너무 게 으르거나 마음이 결여 된 일을하기 위해 그것에 의존하는 n00b 프로그래머들이 있기 때문에 정확하게 그것을 호출하려고 시도하십시오. 따라서 강제 처리를 통해 최종화 close()
가 호출되지 않은 것을 발견 하면 밝은 빨간색 오류 메시지를 기록하여 프로그래머에게 큰 뚱뚱한 모든 대문자를 사용하여 프로그래머에게 자신의 물건을 고칠 것을 지시합니다.
추가 이점으로 소문에 따르면 "JVM은 사소한 finalize () 메소드 (예 : Object 클래스에 정의 된 것과 같은 작업을 수행하지 않고 리턴하는 메소드)를 무시하므로 강제로 폐기하면 모든 마무리를 피할 수 있습니다. 다음 과 같이 메소드 를 코딩 하여 전체 시스템의 오버 헤드 ( 이 오버 헤드가 얼마나 끔찍한 지에 대한 정보는 alip의 답변 참조 ) finalize()
:
@Override
protected void finalize() throws Throwable
{
if( Global.DEBUG && !closed )
{
Log.Error( "FORGOT TO CLOSE THIS!" );
}
//super.finalize(); see alip's comment on why this should not be invoked.
}
이것 뒤에 숨겨진 아이디어 는 컴파일 타임에 값을 알 수 Global.DEBUG
있는 static final
변수이므로 false
컴파일러는 전체 if
명령문에 대해 전혀 코드를 생성하지 않으므로 사소한 (빈) 종결자가됩니다. 클래스가 마치 파이널 라이저가없는 것처럼 취급됩니다. (C #에서는 이것이 멋진 #if DEBUG
블록 으로 수행 되지만, 우리가 할 수있는 일은 뇌에서 추가 오버 헤드가있는 코드에서 명백한 단순성을 지불하는 Java입니다.)
필수 처분에 대한 자세한 내용, 닷넷에서의 자원 처분에 대한 추가 논의와 함께 여기에 : michael.gr : 강제 처분과 "처분 처분"가증
finalize()
는 약간 엉망입니다. 구현 한 경우 동일한 객체의 다른 모든 메소드와 관련하여 스레드로부터 안전해야합니다.