자바 클래스 파일 라이프 스타일

"Under the Hood"의 또 다른 편에 오신 것을 환영합니다. 지난 달의 기사에서는 모든 Java 프로그램이 컴파일되는 추상 컴퓨터 인 JVM (Java Virtual Machine)에 대해 설명했습니다. JVM에 익숙하지 않은 경우이 기사 전에 지난 달 기사를 읽어 보는 것이 좋습니다. 이 기사에서는 Java 클래스 파일의 기본 구조와 라이프 스타일에 대해 간략하게 설명합니다.

여행하기 위해 태어난

Java 클래스 파일은 컴파일 된 Java에 대해 정확하게 정의 된 형식입니다. Java 소스 코드는 모든 JVM에서로드 및 실행할 수있는 클래스 파일로 컴파일됩니다. 클래스 파일은 JVM에 의해로드되기 전에 네트워크를 통해 이동할 수 있습니다.

실제로 Java 가능 브라우저를 통해이 기사를 읽고 있다면 기사 끝 부분에있는 시뮬레이션 애플릿의 클래스 파일이 인터넷을 통해 현재 컴퓨터로 이동하고 있습니다. 음악을 들으려면 (컴퓨터에 오디오 기능이 있음) 다음 버튼을 누릅니다.

이 애플릿을 보려면 Java 사용 가능 브라우저가 필요합니다.

재미있을 것 같군요? 그것은 그들의 본성에 있습니다. Java 클래스 파일은 잘 이동하도록 설계되었습니다. 플랫폼에 독립적이므로 더 많은 곳에서 환영받을 것입니다. 여기에는 JVM에 대한 압축 명령어 세트 인 바이트 코드가 포함되어 있으므로 가볍게 이동할 수 있습니다. Java 클래스 파일은 전 세계의 JVM에 도달하기 위해 끊임없는 속도로 네트워크를 통해 지속적으로 압축됩니다.

클래스 파일에는 무엇이 있습니까?

Java 클래스 파일에는 JVM이 하나의 Java 클래스 또는 인터페이스에 대해 알아야하는 모든 것이 포함되어 있습니다. 클래스 파일에 나타나는 순서대로 주요 구성 요소는 매직, 버전, 상수 풀, 액세스 플래그,이 클래스, 수퍼 클래스, 인터페이스, 필드, 메서드 및 속성입니다.

클래스 파일에 저장된 정보는 종종 길이가 다양합니다. 즉, 클래스 파일을로드하기 전에 정보의 실제 길이를 예측할 수 없습니다. 예를 들어, 메소드 컴포넌트에 나열된 메소드의 수는 소스 코드에 정의 된 메소드 수에 따라 다르기 때문에 클래스 파일마다 다를 수 있습니다. 이러한 정보는 실제 정보를 크기 또는 길이로 시작하여 클래스 파일로 구성됩니다. 이렇게하면 JVM이 클래스를로드 할 때 가변 길이 정보의 크기를 먼저 읽습니다. JVM이 크기를 알고 나면 실제 정보를 올바르게 읽을 수 있습니다.

정보는 일반적으로 연속적인 정보 사이에 공백이나 패딩없이 클래스 파일에 기록됩니다. 모든 것이 바이트 경계에 정렬됩니다. 이렇게하면 클래스 파일을 작게 유지하여 네트워크를 통해 비행 할 때 공기 역학적으로 유지됩니다.

클래스 파일 구성 요소의 순서는 엄격하게 정의되어 있으므로 JVM은 클래스 파일을로드 할 때 예상되는 내용과 예상 할 위치를 알 수 있습니다. 예를 들어 모든 JVM은 클래스 파일의 처음 8 바이트에 매직 및 버전 번호가 포함되어 있고 상수 풀이 9 번째 바이트에서 시작하며 액세스 플래그가 상수 풀을 따른다는 것을 알고 있습니다. 그러나 상수 풀은 가변 길이이므로 상수 풀에서 읽기가 완료 될 때까지 액세스 플래그의 정확한 위치를 알 수 없습니다. 상수 풀에서 읽기를 마치면 다음 2 바이트가 액세스 플래그가 될 것임을 알고 있습니다.

매직 및 버전 번호

모든 클래스 파일의 처음 4 바이트는 항상 0xCAFEBABE입니다. 이 매직 넘버는 비 클래스 파일이 동일한 초기 4 바이트로 시작될 가능성이 적기 때문에 Java 클래스 파일을 더 쉽게 식별 할 수 있습니다. 이 숫자는 파일 형식 디자이너가 모자에서 꺼낼 수 있기 때문에 마법이라고합니다. 유일한 요구 사항은 실제 세계에서 접할 수있는 다른 파일 형식에서 이미 사용되고 있지 않다는 것입니다. 원래 Java 팀의 핵심 멤버 인 Patrick Naughton에 따르면 매직 넘버는 "Java라는 이름이이 언어를 언급하기 훨씬 전에 선택되었습니다. 우리는 재미 있고 독특하며 기억하기 쉬운 것을 찾고있었습니다. Peet 's Coffee의 귀여운 바리 스타에 대한 비스듬한 언급 인 OxCAFEBABE가 Java라는 이름을 예고 한 것은 우연입니다. "

클래스 파일의 두 번째 4 바이트에는 주 및 부 버전 번호가 포함됩니다. 이 번호는 특정 클래스 파일이 준수하는 클래스 파일 형식의 버전을 식별하고 JVM이 클래스 파일을로드 할 수 있는지 확인할 수 있도록합니다. 모든 JVM에는로드 할 수있는 최대 버전이 있으며 JVM은 이후 버전의 클래스 파일을 거부합니다.

상수 풀

클래스 파일은 해당 클래스 또는 인터페이스와 관련된 상수를 상수 풀에 저장합니다. 풀에서 볼 수있는 일부 상수는 리터럴 문자열, 최종 변수 값, 클래스 이름, 인터페이스 이름, 변수 이름 및 유형, 메서드 이름 및 서명입니다. 메서드 시그니처 는 반환 유형과 인수 유형 집합입니다.

상수 풀은 가변 길이 요소의 배열로 구성됩니다. 각 상수는 배열에서 하나의 요소를 차지합니다. 클래스 파일 전체에서 상수는 배열에서의 위치를 ​​나타내는 정수 인덱스로 참조됩니다. 초기 상수는 인덱스가 1이고 두 번째 상수는 인덱스가 2입니다. 상수 풀 배열은 배열 크기가 선행되므로 JVM은 클래스 파일을로드 할 때 예상되는 상수 수를 알 수 있습니다.

상수 풀의 각 요소는 배열의 해당 위치에서 상수 유형을 지정하는 1 바이트 태그로 시작합니다. JVM이이 태그를 잡고 해석하면 태그 뒤에 오는 내용을 알고 있습니다. 예를 들어, 태그가 상수가 문자열임을 나타내는 경우 JVM은 다음 2 바이트가 문자열 길이 일 것으로 예상합니다. 이 2 바이트 길이 다음에 JVM 은 문자열의 문자를 구성하는 길이 바이트 수 를 찾을 것으로 예상 합니다.

이 기사의 나머지 부분에서는 상수 풀 배열의 n 번째 요소를 constant_pool [n]이라고하기도합니다. 이것은 상수 풀이 배열처럼 구성되는 범위에서 의미가 있지만 이러한 요소는 크기와 유형이 다르며 첫 번째 요소의 인덱스는 1이라는 점을 명심하십시오.

액세스 플래그

상수 풀 뒤의 처음 2 바이트 인 액세스 플래그는이 파일이 클래스 또는 인터페이스를 정의하는지 여부, 클래스 또는 인터페이스가 공용인지 추상인지 여부, 클래스가 클래스인지 여부 (인터페이스가 아닌 경우)를 나타냅니다. 최종입니다.

이 수업

다음 2 바이트 인 this 클래스 구성 요소는 상수 풀 배열에 대한 인덱스입니다. 이 클래스가 참조하는 상수 constant_pool [this_class]에는 1 바이트 태그와 2 바이트 이름 색인의 두 부분이 있습니다. 태그는이 요소에 클래스 또는 인터페이스에 대한 정보가 포함되어 있음을 나타내는 값인 CONSTANT_Class와 같습니다. Constant_pool [name_index]는 클래스 또는 인터페이스의 이름을 포함하는 문자열 상수입니다.

이 클래스의 구성 요소는 상수 풀을 사용하는 방법의 한 단면을 제공합니다. 이 클래스 자체는 상수 풀에 대한 인덱스 일뿐입니다. JVM이 constant_pool [this_class]를 조회 할 때 태그가있는 CONSTANT_Class로 자신을 식별하는 요소를 찾습니다. JVM은 CONSTANT_Class 요소가 항상 1 바이트 태그 뒤에 이름 인덱스라고하는 상수 풀에 대한 2 바이트 인덱스를 가지고 있음을 알고 있습니다. 따라서 클래스 또는 인터페이스의 이름을 포함하는 문자열을 얻기 위해 constant_pool [name_index]를 찾습니다.

슈퍼 클래스

이 클래스 구성 요소 다음에는 상수 풀에 대한 또 다른 2 바이트 인덱스 인 수퍼 클래스 구성 요소가 있습니다. Constant_pool [super_class]는이 클래스가 내려 오는 수퍼 클래스의 이름을 가리키는 CONSTANT_Class 요소입니다.

인터페이스

인터페이스 구성 요소는 파일에 정의 된 클래스 (또는 인터페이스)에 의해 구현 된 인터페이스 수의 2 바이트 개수로 시작합니다. 바로 다음은 클래스에 의해 구현 된 각 인터페이스에 대한 상수 풀에 대한 하나의 인덱스를 포함하는 배열입니다. 각 인터페이스는 인터페이스 이름을 가리키는 상수 풀의 CONSTANT_Class 요소로 표시됩니다.

필드

fields 구성 요소는이 클래스 또는 인터페이스에있는 필드 수의 2 바이트 개수로 시작합니다. 필드는 클래스 또는 인터페이스의 인스턴스 또는 클래스 변수입니다. 계수 다음에는 각 필드에 대해 하나씩 가변 길이 구조의 배열이 있습니다. 각 구조는 필드의 이름, 유형 및 최종 변수 인 경우 상수 값과 같은 하나의 필드에 대한 정보를 표시합니다. 일부 정보는 구조 자체에 포함되고 일부는 구조가 가리키는 상수 풀 위치에 포함됩니다.

목록에 나타나는 유일한 필드는 파일에 정의 된 클래스 또는 인터페이스에 의해 선언 된 필드입니다. 수퍼 클래스 또는 수퍼 인터페이스에서 상속 된 필드는 목록에 나타나지 않습니다.

행동 양식

메서드 구성 요소는 클래스 또는 인터페이스에있는 메서드 수의 2 바이트 개수로 시작합니다. 이 수에는이 클래스에 의해 명시 적으로 정의 된 메서드 만 포함되며 슈퍼 클래스에서 상속 될 수있는 메서드는 포함되지 않습니다. 메서드 수 다음에는 메서드 자체가 있습니다.

각 메서드의 구조에는 메서드 설명자 (반환 유형 및 인수 목록), 메서드의 지역 변수에 필요한 스택 단어 수, 메서드의 피연산자에 필요한 최대 스택 단어 수를 포함하여 메서드에 대한 여러 정보가 포함됩니다. 스택, 메서드에 의해 포착 된 예외 테이블, 바이트 코드 시퀀스 및 줄 번호 테이블.

속성

파일에 의해 정의 된 특정 클래스 또는 인터페이스에 대한 일반 정보를 제공하는 속성이 뒤에 있습니다. 속성 섹션에는 속성 수가 2 바이트이고 속성 자체가 뒤 따릅니다. 예를 들어, 하나의 속성은 소스 코드 속성입니다. 이 클래스 파일이 컴파일 된 소스 파일의 이름을 표시합니다. JVM은 인식하지 못하는 속성을 자동으로 무시합니다.

로드하기 : JVM 대상에 도달하는 클래스 파일의 시뮬레이션

아래 애플릿은 클래스 파일을로드하는 JVM을 시뮬레이션합니다. 시뮬레이션에로드되는 클래스 파일은 다음 Java 소스 코드가 지정된 javac 컴파일러에 의해 생성되었습니다.

class Act {public static void doMathForever () {int i = 0; while (true) {i + = 1; 나는 * = 2; }}}

위의 코드 스 니펫은 JVM에 대한 지난 달 기사에서 가져온 것입니다. 지난달 기사에서 EternalMath 애플릿이 실행 한 동일한 doMathForever () 메서드입니다. 너무 복잡하지 않은 실제 예제를 제공하기 위해이 코드를 선택했습니다. 코드가 실제 세계에서 그다지 유용하지 않을 수 있지만 실제 클래스 파일로 컴파일되며 아래 시뮬레이션에 의해로드됩니다.

GettingLoaded 애플릿을 사용하면 한 번에 한 단계 씩 클래스로드 시뮬레이션을 실행할 수 있습니다. 각 단계마다 JVM에서 사용하고 해석 할 다음 바이트 청크에 대해 읽을 수 있습니다. JVM이 다음 청크를 소비하게하려면 "단계"버튼을 누르기 만하면됩니다. "뒤로"를 누르면 이전 단계가 취소되고 "재설정"을 누르면 시뮬레이션이 원래 상태로 돌아가서 처음부터 다시 시작할 수 있습니다.

JVM은 클래스 파일 Act.class를 구성하는 바이트 스트림을 소비하는 왼쪽 하단에 표시됩니다. 바이트는 오른쪽 하단의 서버에서 16 진 스트리밍으로 표시됩니다. 바이트는 서버와 JVM 사이에서 한 번에 하나씩 오른쪽에서 왼쪽으로 이동합니다. 다음 "단계"버튼을 누를 때 JVM이 사용할 바이트 청크는 빨간색으로 표시됩니다. 강조 표시된 바이트는 JVM 위의 큰 텍스트 영역에 설명되어 있습니다. 다음 청크를 초과하는 나머지 바이트는 검은 색으로 표시됩니다.

텍스트 영역의 각 바이트 청크를 완전히 설명하려고 노력했습니다. 따라서 텍스트 영역에는 많은 세부 사항이 있으며 먼저 모든 단계를 훑어 보면서 일반적인 아이디어를 얻은 다음 다시 자세히 살펴볼 수 있습니다.

행복한 클릭.

이 애플릿을 보려면 Java 사용 가능 브라우저가 필요합니다.

GetLoaded의 소스 코드를 보려면 여기를 클릭하십시오. 이 애플릿을 직접 실행하려면이 애플릿이 서버에서 검색하는 두 개의 파일, 각 단계에 대한 텍스트를 포함하는 ASCII 파일과 Act.class 파일 자체가 필요합니다. 플라잉 클래스 파일 오디오 애플릿의 소스 코드를 보려면 여기를 클릭하십시오.

ENDNOTE : 작은 글씨 : "The Java Class File Lifestyle"기사 Copyright (c) 1996 Bill Venners. 판권 소유. "GettingLoaded"애플릿 Copyright (c) 1996 Artima Software Company. 판권 소유.

: END_ENDNOTE

Bill Venners는 Artima Software Company의 사장입니다. Artima를 통해 그는 맞춤형 소프트웨어 개발 및 컨설팅을 수행합니다.

이 주제에 대해 더 알아보기

  • Sun의 공식 단어 인 Java Virtual Machine 사양.

    //java.sun.com/1.0alpha3/doc/vmspec/vmspec_1.html

  • 이 책 나오면 The Java Virtual Machine Specification , //www.aw.com/cp/lindholm-yellin.html, Tim Lindholm과 Frank Yellin (ISBN 0-201-63452-X), The Java의 일부 Addison-Wesley의 시리즈, //www.aw.com/cp/javaseries.html)은 최고의 JVM 리소스가 될 것입니다.
  • 클래스 파일 형식과 바이트 코드 검증기를 설명하는 Java Virtual Machine Specification 4 장의 초안은 JavaSoft에서 검색 할 수 있습니다.

    //java.sun.com/java.sun.com/newdocs.html

이 이야기 "자바 클래스 파일 라이프 스타일"은 원래 JavaWorld에 의해 출판되었습니다.