자바 의 final,finally,finalize 는 어떤 차이 가 있 습 니까?

8304 단어 자바
자바 에서 final,finally,finalize 는 어떤 차이 가 있 습 니까?이것 은 자바 면접 에서 자주 묻 는 질문 인 데,그들 은 도대체 어떤 차이 가 있 습 니까?
이 세 가 지 는 매우 비슷 해 보이 지만,사실 그들의 관 계 는 카 바스 키 와 파키스탄 처럼 키 바 관계 가 있다.
그럼 이 질문 을 받 으 면 어떻게 대답 해 야 하나 요?먼저 문법 과 사용 측면 에서 세 사람의 차 이 를 간단하게 소개 할 수 있다.
  • final 은 클래스,방법,변 수 를 수식 하 는 데 사용 할 수 있 고 각각 다른 의 미 를 가진다.final 수식 의 class 대 표 는 확장 을 계승 할 수 없고 final 의 변 수 는 수정 할 수 없 으 며 final 의 방법 도 다시 쓸 수 없다(override)

  • 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 는 본질 적 으로 빠 른 회수 의 장애물 이 되 어 대상 이 여러 개의 쓰레기 수집 주 기 를 거 쳐 야 회수 할 수 있다
  • finalize 가 쓰레기 수집 을 늦 추어 대량의 대상 이 쌓 이 는 것 도 전형 적 인 OOM 을 초래 하 는 원인 이다

  • 4.567917.회수 자원 을 확보 하려 면 자원 이 모두 유한 하기 때문에 쓰레기 수집 시간의 예측 할 수 없고 자원 의 점용 을 크게 격화 시 킬 수 있다
  • finalize 는 자원 회수 시의 오류 정 보 를 가 릴 수 있 습 니 다

  • 따라서 매우 높 은 주파 수 를 소모 하 는 자원 에 대해 서 는 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 세 사람의 차 이 를 상세 하 게 설명 했다.

    좋은 웹페이지 즐겨찾기