자바 의 final,finally,finalize 는 어떤 차이 가 있 습 니까?
8304 단어 자바
이 세 가 지 는 매우 비슷 해 보이 지만,사실 그들의 관 계 는 카 바스 키 와 파키스탄 처럼 키 바 관계 가 있다.
그럼 이 질문 을 받 으 면 어떻게 대답 해 야 하나 요?먼저 문법 과 사용 측면 에서 세 사람의 차 이 를 간단하게 소개 할 수 있다.
4.567917.finally 는 자바 가 중점 코드 가 반드시 실행 되 어야 한 다 는 메커니즘 이다.try-finally 나 try-catch-finally 를 사용 하여 JDBC 연결 을 닫 고 unlock 잠 금 을 확보 하 는 것 과 같은 동작 을 할 수 있 습 니 다
4.567917.finalize 는 기본 적 인 자바.lang.Object 의 한 방법 으로 디자인 목적 은 대상 이 쓰레기 에 수집 되 기 전에 특정 자원 의 회 수 를 완성 하도록 하 는 것 이다.finalize 메커니즘 은 현재 추천 하지 않 으 며 JDK 9 부터 deprecated 로 표 시 됩 니 다
여기까지 만 대답 하면 하 이 라이트 가 없다.우 리 는 성능,병발,대상 의 생명주기 나 쓰레기 수집 기본 과정 등 측면 에서 자신의 이 해 를 깊이 있 게 소개 할 수 있다.
final
final 키 워드 를 사용 하면 코드 의 의미,논리 적 의 도 를 명확 하 게 나 타 낼 수 있 습 니 다.예 를 들 어:
방법 이나 클래스 를 final 로 성명 할 수 있 으 며,이러한 행 위 는 수정 할 수 없다 는 것 을 명확 하 게 알려 줄 수 있다.자바 핵심 라 이브 러 리 의 정의 나 소스 코드,예 를 들 어 자바.lang 패키지 아래 의 여러 가지 유형,상당 부분 은 final class 로 밝 혀 졌 습 니 다.예 를 들 어 우리 가 흔히 볼 수 있 는 String 류 는 제3자 라 이브 러 리 의 일부 기본 클래스 에서 마찬가지 로 API 사용자 가 기본 기능 을 변경 하 는 것 을 효과적으로 피 할 수 있 습 니 다.어느 정도 에 이것 은 플랫폼 의 안전 을 확보 하 는 필수 적 인 수단 입 니 다.
final 수식 매개 변수 나 변 수 를 사용 하면 예상 치 못 한 할당 으로 인 한 프로 그래 밍 오 류 를 뚜렷하게 피 할 수 있 습 니 다.심지어 모든 방법 파라미터,로 컬 변수,구성원 변 수 를 final 로 설명 하 는 것 을 명 확 히 추천 합 니 다.
final 변 수 는 어느 정도 가 변 적 이지 않 은(immutable)효 과 를 가 져 왔 기 때문에 읽 기 전용 데 이 터 를 보호 하 는 데 사용 할 수 있 습 니 다.특히 병행 프로 그래 밍 에서 final 변 수 를 명확 하 게 부여 하지 못 하기 때문에 추가 적 인 동기 화 비용 을 줄 이 고 방어 적 인 복사 의 필요 성 을 줄 일 수 있 습 니 다.
final 은 성능 의 좋 은 점 이 있 을 수 있 습 니 다.많은 글 이나 책 에서 특정한 장면 에서 성능 을 향상 시 킬 수 있 습 니 다.예 를 들 어 final 을 이용 하면 JVM 이 방법 을 내부 연결 하 는 데 도움 이 되 고 컴 파일 러 가 조건 부 컴 파일 을 하 는 능력 을 개선 할 수 있 습 니 다.나 는 이전 글 에 소 개 를 했 으 니 알 고 싶 은 것 은 클릭 하여 찾 아 볼 수 있다.
확장 읽 기:자바 의 final 키 워드 를 깊이 이해 합 니 다.
final 과 immutable
앞에서 final 이 실천 에서 의 이점 을 소개 했다.주의해 야 할 것 은 final 은 immutable 과 같 지 않다 는 것 이다.예 를 들 어 다음 코드 와 같다.
final List strList = new ArrayList<>();
strList.add("wupx");
strList.add("huxy");
List loveList = List.of("wupx", "huxy");
loveList.add("love");
final 은 strList 만 제약 할 수 있 습 니 다.이 인용 은 할당 되 지 않 지만 strList 대상 의 행 위 는 final 에 영향 을 받 지 않 고 요 소 를 추가 하 는 등 조작 이 정상 적 입 니 다.만약 우리 가 정말 대상 자체 가 변 하지 않 기 를 원한 다 면,상응하는 종류의 변 하지 않 는 행 위 를 지지 해 야 한다.위의 예 에서 List.of 방법 은 자체 가 가 변 적 이지 않 은 List 입 니 다.마지막 으로 그 add 는 실 행 될 때 이상 을 던 집 니 다.
Immutable 은 많은 장면 에서 매우 좋 은 선택 입 니 다.특정한 의미 에서 자바 언어 는 현재 원생 의 불가 변 지원 이 없습니다.immutable 류 를 실현 하려 면 우 리 는 해 야 합 니 다.
클 라 스 자 체 를 final 로 선언 하면 다른 사람 이 제한 을 피해 확장 할 수 없습니다.
모든 구성원 변 수 를 private 와 final 로 정의 하고 setter 방법 을 실현 하지 마 십시오.
일반적으로 대상 을 구성 할 때 구성원 변 수 는 깊이 있 는 복사 로 초기 화 됩 니 다.직접 값 을 부여 하 는 것 이 아니 라 방어 조치 입 니 다.입력 대상 이 다른 사람 에 게 수정 되 지 않 는 다 는 것 을 확인 할 수 없 기 때 문 입 니 다.
getter 방법 이 필요 하거나 내부 상태 로 돌아 갈 수 있 는 다른 방법 이 필요 하 다 면 copy-on-write 원칙 을 사용 하여 개인 적 인 copy 를 만 듭 니 다.
setter/getter 방법 에 대해 서 는 IDE 나 Lombok 으로 한 번 에 모두 생 성 하 는 것 을 좋아 하 는 사람 이 많 으 므 로 필요 할 때 다시 실현 하 는 것 이 좋 습 니 다.
finally
finally 에 대해 서 는 어떻게 사용 하 는 지 알 면 충분 합 니 다.닫 아야 할 연결 등 자원 은 자바 7 에 추 가 된 try-with-resources 문 구 를 사용 하 는 것 을 추천 합 니 다.보통 자바 플랫폼 은 이상 상황 을 잘 처리 하고 코드 량 도 줄 일 수 있 기 때 문 입 니 다.
또 자주 시험 을 보 는 finally 문제 도 있다.예 를 들 어 아래 코드 는 무엇 을 출력 합 니까?
try {
// do something
System.exit(1);
} finally{
System.out.println("Hello,I am finally。");
}
위의 finally 안의 코드 는 실행 되 지 않 습 니 다.try-catch 가 이상 하 게 종료 되 었 기 때 문 입 니 다.
다른 finally 의 코드 가 실행 되 지 않 을 경우:
//
try{
while(ture){
System.out.println("always run");
}
}finally{
System.out.println("ummm");
}
//
try-finally ,finally 。
finalize
finalize 에 대해 서 는 추천 하지 않 습 니 다.자바 9 에 서 는 Object.finalize()를 deprecated 로 표시 하 였 습 니 다.
왜 일 까요?finalize 가 언제 실 행 될 지,예상 에 맞 게 실 행 될 지 장담 할 수 없 기 때문이다.잘못 사용 하면 성능 에 영향 을 주 고 프로그램 이 잠 겨 있 거나 걸 려 있 는 등 으로 이 어 질 수 있다.
일반적으로 위 에서 언급 한 try-with-resources 나 try-finally 체 제 를 이용 하 는 것 은 자원 을 회수 하 는 좋 은 방법 이다.추가 처리 가 필요 하 다 면 자바 가 제공 하 는 클 리 너 체제 나 다른 대체 방법 을 고려 할 수 있다.
왜 finalize 를 추천 하지 않 습 니까?
앞에서 간단하게 finalize 는 추천 하지 않 고 사용 하 는 것 을 소 개 했 는데 도대체 왜 추천 하지 않 습 니까?
4.567917.finalize 의 집행 은 쓰레기 수집 과 관련 된 것 으로 비 어 있 는 finalize 방법 을 실현 하면 해당 대상 의 회수 가 수량 급 에서 느 려 집 니 다
4.567917.finalize 는 대상 이 쓰레기 수집 전에 호출 되 는 것 으로 설계 되 었 고 JVM 은 이 를 추가 로 처리 해 야 한다.finalize 는 본질 적 으로 빠 른 회수 의 장애물 이 되 어 대상 이 여러 개의 쓰레기 수집 주 기 를 거 쳐 야 회수 할 수 있다
4.567917.회수 자원 을 확보 하려 면 자원 이 모두 유한 하기 때문에 쓰레기 수집 시간의 예측 할 수 없고 자원 의 점용 을 크게 격화 시 킬 수 있다
따라서 매우 높 은 주파 수 를 소모 하 는 자원 에 대해 서 는 finalize 가 자원 방출 의 주요 직책 을 맡 기 를 기대 하지 마 세 요.자원 을 다 쓰 면 명시 적 으로 방출 하거나 자원 탱크 를 이용 하여 최대한 재 활용 하 는 것 을 권장 합 니 다.
다음은 finalize 가 자원 회수 시 오류 정 보 를 가 리 는 예 를 들 어 자바.lang.ref.finalizer 의 소스 코드 를 보 여 줍 니 다.
private void runFinalizer(JavaLangAccess jla) {
// ...
try {
Object finalizee = this.get();
if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
jla.invokeFinalize(finalizee);
// Clear stack slot containing this variable, to decrease
// the chances of false retention with a conservative GC
finalizee = null;
}
} catch (Throwable x) { }
super.clear();
}
이전에 이상 한 글 을 설명 한 친 구 를 보면 Throwable 이 삼 켜 졌 다 는 것 을 금방 알 수 있 을 것 이다.즉,이상 이 생기 거나 오류 가 발생 하면 효과 적 인 정 보 를 얻 지 못 한 다 는 것 을 의미한다.
확장 읽 기:자바 이상 처리 의 20 가지 가장 좋 은 실천,당신 은 몇 가 지 를 알 고 있 습 니까?
finalize 를 대체 할 더 좋 은 방법 이 있 습 니까?
자바 플랫폼 은 현재 자바.lang.ref.Cleaner 를 사용 하여 기 존의 finalize 를 교체 하고 있 습 니 다.Cleaner 의 실현 은 환상 인용(Phantom Reference)을 이용 하 는데 이것 은 흔히 볼 수 있 는 post-mortem 청소 메커니즘 이다.환상 참조 와 인용 대기 열 을 이용 하여 대상 이 완전히 소각 되 기 전에 유사 한 자원 회수 작업 을 할 수 있 습 니 다.예 를 들 어 파일 설명자(운영 체제 에 제 한 된 자원)를 닫 으 면 finalize 보다 더 가 볍 고 신뢰 할 수 있 습 니 다.
모든 Cleaner 의 조작 은 독립 적 이 고 자신의 운행 라인 이 있 기 때문에 의외 의 잠 금 등 문 제 를 피 할 수 있 습 니 다.
우 리 는 자신의 모듈 에 Cleaner 를 구축 한 다음 에 해당 하 는 청소 논 리 를 실현 할 수 있 습 니 다.구체 적 인 코드 는 다음 과 같 습 니 다.
/**
* Cleaner , finalize
* Cleaner , , GC
*
*
* ( Runnable) 。 :
* 1. Object
* 2. clean
*
*
* , ( )
* Cleanable clean
* ( state),
* State , CleaningExample clean,
* ,
*/
public class CleaningExample implements AutoCloseable {
public static void main(String[] args) {
try {
// JDK7 try with Resources clean
try (CleaningExample ignored = new CleaningExample()) {
throw new RuntimeException();
}
} catch (RuntimeException ignored) {
}
// GC clean
new CleaningExample();
System.gc();
}
private static final Cleaner CLEANER = Cleaner.create();
// ,
static class State implements Runnable {
State() {
}
@Override
public void run() {
System.out.println("Cleaning called");
}
}
private final State state;
private final Cleaner.Cleanable cleanable;
public CleaningExample() {
this.state = new State();
this.cleanable = CLEANER.register(this, state);
}
@Override
public void close() {
cleanable.clean();
}
}
그 중에서 State 를 static 로 정의 하 는 것 은 일반적인 내부 클래스 에 외부 대상 에 대한 강 한 인용 이 포함 되 어 있 는 것 을 피하 기 위해 서 입 니 다.그러면 외부 대상 이 환상 적 으로 접근 할 수 있 는 상태 에 들 어 갈 수 없 기 때 문 입 니 다.
예측 가능 한 측면 에서 볼 때 클 리 너 나 환상 인용 개선 정 도 는 여전히 한계 가 있 으 며,여러 가지 원인 으로 인해 환상 인용 이 쌓 이면 문제 가 발생 할 수 있다.따라서 클 리 너 는 클 리 너 에 게 완전히 의존 하여 자원 을 회수 하 는 것 이 아니 라 마지막 보증 수단 으로 적합 하 다.
총결산
이 글 은 먼저 문법 적 측면 에서 final,finally,finalize 를 분석 하고 안전,성능,쓰레기 수집 등 측면 에서 점차적으로 깊이 있 게 final,finally,finalize 세 사람의 차 이 를 상세 하 게 설명 했다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.