자바 류 로드 메커니즘 과 반사 상세 및 인 스 턴 스 코드

자바 클래스 로드 메커니즘
1.개술
       Class 파일 은 클래스 로 더 에 불 러 온 후 JVM 에서 Class 구 조 를 설명 하 는 메타 정보 대상 을 형성 합 니 다.이 메타 정보 대상 을 통 해 Class 의 구조 정 보 를 알 수 있 습 니 다.예 를 들 어 구조 함수,속성 과 방법 등 자바 는 사용자 가 이 Class 와 관련 된 메타 정보 대상 을 빌려 Class 대상 의 기능 을 간접 적 으로 호출 할 수 있 습 니 다.
      가상 컴퓨터 는 설명 류 의 데 이 터 를 class 파일 에서 메모리 로 불 러 오고 데 이 터 를 검증 하 며 분석 과 초기 화 를 하여 가상 컴퓨터 가 직접 사용 할 수 있 는 자바 형식 을 형성 합 니 다.이것 이 바로 가상 컴퓨터 의 클래스 로드 메커니즘 입 니 다.
2.작업 메커니즘
      클래스 로 더 는 클래스 의 바이트 파일 을 찾 고 JVM 내부 에 표 시 된 대상 구성 요 소 를 구성 하 는 것 입 니 다.자바 에 서 는 클래스 로 더 가 하나의 클래스 를 JVM 에 불 러 오 려 면 다음 절 차 를 거 쳐 야 합 니 다.
     (1) 불 러 오기:Class 파일 찾기 및 가 져 오기;
     (2) 링크:클래스 의 바 이 너 리 데 이 터 를 JRE 에 통합 합 니 다.
        (a)검사:Class 파일 데 이 터 를 불 러 오 는 정확성 을 검사 합 니 다.
        (b)준비:클래스 의 정적 변수 에 저장 공간 을 분배 합 니 다.
        (c)해석:기호 인용 을 직접 인용 으로 변환 합 니 다.
     (3) 초기 화:클래스 의 정적 변수,정적 코드 블록 에 대한 초기 화 작업

       자바 프로그램 이 동적 으로 확장 할 수 있 는 것 은 실행 기 동적 로드 와 동적 링크 에 의 해 이 루어 집 니 다.예 를 들 어 인 터 페 이 스 를 사용 하 는 프로그램 을 만 들 면 실행 할 때 실제 구현(다 중)을 지정 할 수 있 습 니 다.분석 과정 은 초기 화 된 후에 도 실 행 될 수 있 습 니 다.예 를 들 어 동적 바 인 딩(다 중);       
      【클래스 초기 화] 
      (1) new,getstatic,putstatic 또는 invokstatic 등 4 개의 바이트 코드 명령 을 만 났 을 때 클래스 가 초기 화 되 지 않 았 다 면 초기 화 를 먼저 실행 해 야 합 니 다.이 네 가지 명령 을 만 드 는 가장 흔 한 자바 코드 장면 은 new 키 워드 를 사용 하여 대상 을 예화 할 때 하나의 정적 필드(final 에 의 해 수식 되 고 컴 파일 기간 에 결 과 를 상수 탱크 에 넣 은 정적 필드 제외)를 읽 거나 설정 할 때,그리고 하나의 정적 방법 을 호출 할 때 입 니 다.
      (2) 자바.lang.reflect 패 키 지 를 사용 하여 클래스 를 반사 호출 할 때 클래스 가 초기 화 되 지 않 았 다 면 초기 화 를 먼저 촉발 해 야 합 니 다.
      (3) 클래스 를 초기 화 할 때 부모 클래스 가 초기 화 되 지 않 은 것 을 발견 하면 먼저 부모 클래스 의 초기 화 를 촉발 해 야 합 니 다.
      (4)가상 컴퓨터 가 시 작 될 때 사용 자 는 실행 할 주 클래스(main()방법 을 포함 하 는 클래스)를 지정 해 야 합 니 다.가상 기 회 는 이 주 클래스 를 초기 화 합 니 다.
상기 네 가지 상황 만 초기 화 를 촉발 할 수 있 습 니 다.한 클래스 에 대해 주동 적 으로 인용 하 는 것 이 라 고도 합 니 다.이 를 제외 하고 모든 다른 방식 은 초기 화 를 촉발 하지 않 습 니 다.수 동적 인용 이 라 고도 합 니 다.
코드 목록 1

 상기 코드 가 실 행 된 후 출력 만 할 수 있 습 니 다. init】, 출력 하지 않 음[SubClass init]정적 필드 에 대해 서 는 이 필드 의 클래스 를 직접 정의 해 야 초기 화 됩 니 다.따라서 하위 클래스 를 통 해 부모 클래스 의 정적 필드 를 호출 하면 부모 클래스 의 초기 화 만 촉발 할 수 있 습 니 다.그러나 이것 은 서로 다른 가상 컴퓨터 의 서로 다른 실현 을 봐 야 합 니 다.
코드 목록 2

 SuperClass 초기 화 를 일 으 키 지 는 않 지만[Ltest.SuperClass]초기 화 를 실 행 했 습 니 다.arr.toString()을 통 해 알 수 있 듯 이 사용자 코드 에 있어 서 이것 은 합 법 적 인 클래스 이름 이 아 닙 니 다.가상 컴퓨터 에서 자동 으로 생 성 되 고 Object 의 하위 클래스 에 직접 계승 되 며 생 성 동작 은 바이트 명령 newarray 에서 실 행 됩 니 다.이 때 배열 의 크로스 오 버 검 사 는 배열 대상 의 모든 호출 과정 에 수반 된다.크로스 오 버 검 사 는 배열 요소 가 방문 하 는 클래스 에 포 장 된 것 이 아니 라 배열 이 방문 하 는 xaload,xastore 바이트 코드 명령 에 포 장 된 것 이다.
코드 목록 3

 상수 ConstClass.value 의 인용 은 실제 적 으로 NotInitialization 류 가 자신의 상수 탱크 에 대한 인용 으로 바 뀌 었 으 며,이 두 종 류 는 class 로 컴 파일 된 후 아무런 관계 가 없습니다.
          【적재 하 다
    적재 단계 에서 가상 컴퓨터 는 다음 과 같은 세 가지 일 을 완성 해 야 한다.
        (1) 클래스 의 전체 한정 명 을 통 해 이러한 바 이 너 리 바이트 흐름 을 정의 합 니 다.
        (2) 이 바이트 흐름 이 대표 하 는 정적 저장 구 조 를 방법 구역 의 운행 시 데이터 구조 로 전환 합 니 다.
        (3) 자바 더미 에 이 종 류 를 대표 하 는 자바.lang.Class 대상 을 생 성하 여 방법 구역 으로 이 데이터 의 접근 입 구 를 만 듭 니 다.
    가상 컴퓨터 규범 에 서 는 바 이 너 리 바이트 흐름 을 어디서 가 져 오고 어떻게 가 져 와 야 하 는 지 정확하게 설명 하지 않 았 습 니 다.여 기 는 자신의 클래스 로 더 를 정의 하여 바이트 흐름 을 제어 하 는 방식 을 사용 할 수 있 습 니 다.        
         【검증
    가상 컴퓨터 가 입력 한 바이트 흐름 을 검사 하지 않 고 완전히 신뢰 하면 유해 한 바이트 흐름 을 불 러 와 시스템 이 무 너 질 수 있 습 니 다. 
         【준비
    준비 단 계 는 클래스 변 수 를 정식으로 분배 하고 클래스 변수의 초기 값 을 설정 하 는 단계 입 니 다.이 메모리 들 은 모두 방법 영역 에서 분 배 됩 니 다.설명 할 것 은:
이 때 메모리 분 배 는 클래스 변수(static 에 의 해 수 정 된 변수)만 포함 하고 인 스 턴 스 변 수 는 대상 이 예화 될 때 대상 과 함께 자바 더미 에 분 배 됩 니 다.여기 서 말 하 는 초기 값"일반적인 상황"은 데이터 형식의 0 값 입 니 다.만약:

public static int value = 123;
value 는 준비 단계 가 끝 난 후 초기 값 이 0 이지 123 이 아 닙 니 다.value 가 할당 한 putstatic 명령 은 초기 화 단계 에서 실 행 됩 니 다.
2.카 운 터 와 부모 위임 모델
      클래스 로 더
     (1) Bootstrap ClassLoader : \lib 디 렉 터 리 에 있 거나-Xbootclasspath 매개 변수 가 지정 한 경로 에 있 으 며 가상 컴퓨터 로 인식 되 어 있 습 니 다(예 를 들 어 파일 이름 으로 만 식별 합 니 다. rt.jar 이름 이 맞지 않 는 라 이브 러 리 는 lib 디 렉 터 리 에 넣 어도 불 러 오지 않 습 니 다)라 이브 러 리 는 가상 컴퓨터 메모리 에 불 러 옵 니 다.시작 클래스 로 더 는 자바 프로그램 에서 직접 참조 할 수 없습니다.
     (2) Extension ClassLoader : 장\lib\ext 디 렉 터 리 에 있 거나 자바 ext.dirs 시스템 변수 가 지정 한 경로 의 모든 라 이브 러 리 에 불 러 옵 니 다.개발 자 는 확장 클래스 로 더 를 직접 사용 할 수 있 습 니 다.
     (3) Application ClassLoader : 사용자 클래스 경로(ClassPath)에서 지정 한 라 이브 러 리 를 불 러 옵 니 다.개발 자 는 직접 사용 할 수 있 습 니 다.     
양친 위임 모델

 작업 과정:클래스 로 딩 요청 을 받 으 면 먼저 이 요청 을 부모 클래스 로 딩 에 의뢰 합 니 다.각 단계 의 클래스 로 딩 요청 이 이 렇 기 때문에 모든 로 딩 요청 은 맨 위 에 있 는 시작 클래스 로 전송 해 야 합 니 다.부모 로 더 가 이 로 더 요청 을 완료 할 수 없 음 을 피드백 할 때 만 하위 로 더 는 스스로 불 러 오 려 고 시도 합 니 다.
     장점:자바 류 는 클래스 로 더 와 함께 우선 순위 가 있 는 계층 관 계 를 갖 추고 있 습 니 다.예 를 들 어 클래스 java.lang.Object 는 rt.jar 에 저 장 됩 니 다.어떤 종류의 로 더 를 불 러 오 든 최종 적 으로 시작 클래스 로 더 를 불 러 오 라 고 위임 합 니 다.따라서 Object 류 는 프로그램의 다양한 종류의 로 더 환경 에서 같은 클래스 입 니 다.반면 사용자 가 자바.lang.Object 라 는 클래스 를 직접 쓰 고 프로그램의 Classpath 에 넣 으 면 시스템 에 여러 개의 Object 클래스 가 나타 나 고 자바 형식 시스템 에서 가장 기본 적 인 행동 도 장담 할 수 없 으 며 응용 프로그램 도 혼 란 스 러 워 집 니 다.
       java.lang.ClassLoader 에서 가장 중요 한 몇 가지 방법:

//      (    )      ,        
public Class<?> loadClass(String name);
//      (    )      ,        (  ,   resolve               ),    
protected synchronized Class<?> loadClass(String name, boolean resolve);
protected Class<?> findClass(String name)
//    ,   findClass              ,        (  :JVM            ,        ,                 ,      ,        )
protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError{}
다음은 부모 위임 모델 을 실현 하 는 주요 코드 입 니 다.
 
반사
      Reflection 메커니즘 은 프로그램 이 실행 중인 과정 에서 Reflection 을 이용 할 수 있 도록 합 니 다. API 는 패키지, type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructors、 methods、 modifiers 등 을 실행 하 는 과정 에서 인 스 턴 스 를 동적 으로 생 성하 거나 fields 내용 을 변경 하거나 methods 를 불 러 일 으 킬 수 있 습 니 다.
      1.구조 획득 방법
Class 클래스 는 어떤 종류의 구조 방법 을 얻 기 위해 네 개의 Public 방법 을 제공 합 니 다.
Constructor getConstructor(Class[] params)     
구조 함수 의 매개 변수 에 따라 구체 적 인 Public 속성 을 가 진 구조 함 수 를 되 돌려 줍 니 다.
    Constructor getConstructors()     
Public 속성 을 가 진 모든 구조 함수 배열 을 되 돌려 줍 니 다.
    Constructor getDeclaredConstructor(Class[] params)     
구조 함수 의 매개 변수 에 따라 구체 적 인 구조 함수(Public 와 비 Public 속성 을 가리 지 않 음)를 되 돌려 줍 니 다.
    Constructor getDeclaredConstructors()    
이 클래스 의 모든 구조 함수 배열 을 되 돌려 줍 니 다(Public 와 비 Public 속성 을 구분 하지 않 음)

 2,획득 클래스 의 구성원 방법
구조 방법 을 얻 는 방식 과 마찬가지 로 네 가지 구성원 을 얻 는 방법 이 존재 한다. 
Method getMethod(String name, Class[] params)    
방법 이름과 매개 변수 에 따라 구체 적 인 Public 속성 을 가 진 방법 을 되 돌려 줍 니 다.
    Method[] getMethods()    
Public 속성 을 가 진 모든 방법 배열 을 되 돌려 줍 니 다.
    Method getDeclaredMethod(String name, Class[] params)    
방법 이름과 매개 변수 에 따라 구체 적 인 방법 을 되 돌려 줍 니 다(Public 와 비 Public 속성 을 가리 지 않 음)
    Method[] getDeclaredMethods()    
이 클래스 의 모든 방법 을 되 돌려 줍 니 다.

 3.클래스 의 구성원 변수 가 져 오기(구성원 속성)
멤버 속성 을 얻 는 네 가지 방법 이 존재 합 니 다.
    Field getField(String name)    
변수 이름 에 따라 구체 적 인 Public 속성 을 가 진 구성원 변 수 를 되 돌려 줍 니 다.
    Field[] getFields()  
Public 속성 을 가 진 구성원 변수의 그룹 을 되 돌려 줍 니 다.
    Field getDeclaredField(String name)  
변수 이름 에 따라 구성원 변 수 를 되 돌려 줍 니 다.(Public 와 비 Public 속성 을 구분 하지 않 음)
    Field[] getDelcaredFields()    
모든 구성원 변수 로 구 성 된 배열 을 되 돌려 줍 니 다.(Public 와 비 Public 속성 을 구분 하지 않 음)
 참고:
《JVM 가상 머 신 깊이 이해》
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기