finalize 사용 방지
고전 읽기-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.runFinalizersOnExit
와Runtime.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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.