자바 클래스 파일은 자바 가상 머신(JVM)에서 실행될 수 있는 바이트코드를 포함하는 이진 파일 형식이다. 2006년 JSR 202에 따라 클래스 파일 형식이 수정되었다. 클래스 파일은 매직 넘버(0xCAFEBABE), 클래스 파일 형식 버전, 상수 풀, 접근 플래그, 현재 클래스, 슈퍼 클래스, 인터페이스, 필드, 메서드, 속성 등 10가지 항목으로 구성된다. 클래스 파일은 가변 크기 항목을 포함하며, 파일 내 오프셋을 명시적으로 포함하지 않고, 파일의 처음부터 끝까지 순차적으로 분석된다.
더 읽어볼만한 페이지
자바 플랫폼 - 블루레이 블루레이 디스크는 DVD 후속 매체로, 청색 레이저를 사용하여 고화질 영상과 음향을 제공하며 HD DVD와의 경쟁 후 고밀도 광디스크 표준으로 자리 잡았으나 스트리밍 서비스 성장으로 녹화용 디스크 생산이 중단되는 추세이다.
자바 플랫폼 - 자바 플랫폼, 마이크로 에디션 자바 ME는 임베디드 및 모바일 장치에서 자바 앱을 실행하는 플랫폼으로, 피처폰에서 주로 사용되었으며 다양한 프로파일과 에뮬레이터, 개발 도구를 제공하고 JSR을 통해 기능이 확장된다.
파일 포맷 - 바로 가기 바로 가기는 운영체제에서 파일, 폴더, 프로그램, 웹 페이지에 대한 참조를 제공하는 기능 및 파일로, 사용자들이 원본에 빠르게 접근하도록 GUI 환경의 사용성을 향상시킨다.
파일 포맷 - EXE EXE 파일 형식은 운영 체제에 따라 다양한 종류가 있는 실행 파일의 한 형태로, DOS MZ 실행 파일에서 PE, PE32+까지 발전해 왔으며, 코드, 데이터, 스택을 별도 관리하고 재배치 항목을 통해 실행 환경에 유연하게 대응하는 특징을 가진다.
자바 클래스 파일은 4 바이트헤더 (16진수) CA FE BA BE로 식별된다. 이 매직 넘버의 역사에 대해 제임스 고슬링은 팔로알토에 있는 한 식당을 언급하며 다음과 같이 설명했다:[2]
> "우리는 St Michael's Alley라는 곳에서 점심을 먹곤 했습니다. 현지 전설에 따르면, 아주 오래전, 그레이트풀 데드는 유명해지기 전에 그곳에서 공연을 하곤 했습니다. 그곳은 정말 펑키한 곳이었고, 분명 그레이트풀 데드 스타일의 장소였습니다. 제리 가르시아가 죽었을 때는 작은 불교식 사당까지 세웠죠. 우리가 그곳에 갈 때, 우리는 그곳을 Cafe Dead라고 불렀습니다. 그러던 중, 이것이 16진수 숫자라는 것을 알게 되었습니다. 저는 파일 형식 코드를 개정하고 있었고, 몇 개의 매직 넘버가 필요했습니다. 하나는 영구 객체 파일용이고, 다른 하나는 클래스용이었습니다. 저는 객체 파일 형식에 CAFEDEAD를 사용했고, "CAFE" 뒤에 맞는 4글자 16진수 단어를 grep으로 찾다가 (좋은 테마 같아 보였습니다) BABE를 발견하고 사용하기로 결정했습니다. 그 당시에는 별로 중요하지 않거나 역사의 쓰레기통으로 갈 운명이라고 생각하지 않았습니다. 그래서 CAFEBABE가 클래스 파일 형식이 되었고, CAFEDEAD가 영구 객체 형식이 되었습니다. 그러나 영구 객체 기능은 사라졌고, CAFEDEAD의 사용도 함께 사라졌습니다. 결국 RMI로 대체되었습니다."
3. 3. 일반적인 레이아웃
0xCA (16진수)
매직 넘버 (CAFEBABE)는 파일을 클래스 파일 형식에 부합하는 것으로 식별하는 데 사용됨
1
u1 = 0xFE (16진수)
2
u1 = 0xBA (16진수)
3
u1 = 0xBE (16진수)
4
2바이트
u2
사용 중인 클래스 파일 형식의 마이너 버전 번호
5
6
2바이트
u2
사용 중인 클래스 파일 형식의 메이저 버전 번호.[3]
7
8
2바이트
u2
상수 풀 개수, 다음 상수 풀 테이블의 항목 수. 이 개수는 실제 항목 수보다 최소 1만큼 큼.
9
10
cpsize (가변)
table
상수 풀 테이블, 리터럴 숫자, 문자열 및 클래스 또는 메서드에 대한 참조와 같은 항목을 포함하는 가변 크기 상수 풀 항목. 1부터 시작하여 인덱싱되며 총 (constant pool count - 1)개의 항목을 포함.
...
...
...
10+cpsize
2바이트
u2
액세스 플래그, 비트 마스크
11+cpsize
12+cpsize
2바이트
u2
this 클래스를 식별하고, "Class" 유형 항목의 상수 풀에 대한 인덱스
13+cpsize
14+cpsize
2바이트
u2
super 클래스를 식별하고, "Class" 유형 항목의 상수 풀에 대한 인덱스
15+cpsize
16+cpsize
2바이트
u2
인터페이스 개수, 다음 인터페이스 테이블의 항목 수
17+cpsize
18+cpsize
isize (가변)
table
인터페이스 테이블: 이 클래스에서 구현된 인터페이스를 설명하는 가변 길이 상수 풀 인덱스 배열
...
...
...
18+cpsize+isize
2바이트
u2
필드 개수, 다음 필드 테이블의 항목 수
19+cpsize+isize
20+cpsize+isize
fsize (가변)
table
필드 테이블, 가변 길이 필드 배열. 각 요소는 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5 에 정의된 field_info 구조체.
...
...
...
20+cpsize+isize+fsize
2바이트
u2
메서드 개수, 다음 메서드 테이블의 항목 수
21+cpsize+isize+fsize
22+cpsize+isize+fsize
msize (가변)
table
메서드 테이블, 가변 길이 메서드 배열. 각 요소는 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6 에 정의된 method_info 구조체.
...
...
...
22+cpsize+isize+fsize+msize
2바이트
u2
속성 개수, 다음 속성 테이블의 항목 수
23+cpsize+isize+fsize+msize
24+cpsize+isize+fsize+msize
asize (가변)
table
속성 테이블, 가변 길이 속성 배열. 각 요소는 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7 에 정의된 attribute_info 구조체.
...
...
...
3. 4. 상세 레이아웃 테이블
0xCA (16진수)
매직 넘버 (CAFEBABE)는 파일을 클래스 파일 형식에 부합하는 것으로 식별하는 데 사용됨
1
u1 = 0xFE (16진수)
2
u1 = 0xBA (16진수)
3
u1 = 0xBE (16진수)
4
2바이트
u2
사용 중인 클래스 파일 형식의 마이너 버전 번호
5
6
2바이트
u2
사용 중인 클래스 파일 형식의 메이저 버전 번호.[3]
7
8
2바이트
u2
상수 풀 개수, 다음 상수 풀 테이블의 항목 수. 이 개수는 실제 항목 수보다 최소 1만큼 큼.
9
10
cpsize (가변)
table
상수 풀 테이블, 리터럴 숫자, 문자열 및 클래스 또는 메서드에 대한 참조와 같은 항목을 포함하는 가변 크기 상수 풀 항목의 배열. 1부터 시작하여 인덱싱되며 총 (constant pool count - 1)개의 항목을 포함함.
...
...
...
10+cpsize
2바이트
u2
액세스 플래그, 비트 마스크
11+cpsize
12+cpsize
2바이트
u2
this 클래스를 식별하고, "Class" 유형 항목의 상수 풀에 대한 인덱스
13+cpsize
14+cpsize
2바이트
u2
super 클래스를 식별하고, "Class" 유형 항목의 상수 풀에 대한 인덱스
15+cpsize
16+cpsize
2바이트
u2
인터페이스 개수, 다음 인터페이스 테이블의 항목 수
17+cpsize
18+cpsize
isize (가변)
table
인터페이스 테이블: 이 클래스에서 구현된 인터페이스를 설명하는 가변 길이 상수 풀 인덱스 배열
...
...
...
18+cpsize+isize
2바이트
u2
필드 개수, 다음 필드 테이블의 항목 수
19+cpsize+isize
20+cpsize+isize
fsize (가변)
table
필드 테이블, 가변 길이 필드 배열. 각 요소는 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5에 정의된 field_info 구조체임.
...
...
...
20+cpsize+isize+fsize
2바이트
u2
메서드 개수, 다음 메서드 테이블의 항목 수
21+cpsize+isize+fsize
22+cpsize+isize+fsize
msize (가변)
table
메서드 테이블, 가변 길이 메서드 배열. 각 요소는 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6에 정의된 method_info 구조체임.
...
...
...
22+cpsize+isize+fsize+msize
2바이트
u2
속성 개수, 다음 속성 테이블의 항목 수
23+cpsize+isize+fsize+msize
24+cpsize+isize+fsize+msize
asize (가변)
table
속성 테이블, 가변 길이 속성 배열. 각 요소는 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7에 정의된 attribute_info 구조체임.
...
...
...
4. C와 유사한 프로그래밍 언어에서의 표현
C는 구조체 내에서 가변 길이 배열을 지원하지 않으므로, 아래 코드는 컴파일되지 않으며 단지 예시로만 사용된다.
```c
struct Class_File_Format {
u4 magic_number;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count - 1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
};
5. 상수 풀
상수 풀은 자바 클래스 파일 구조에서 대부분의 리터럴 상수 값을 저장하는 곳으로, 숫자, 문자열, 식별자 이름, 클래스 및 메서드 참조, 타입 설명자 등을 포함한다.[6] 상수 풀 내의 특정 상수에 대한 모든 인덱스나 참조는 16비트(u2 타입) 숫자로 제공되며, 인덱스 값 1은 테이블의 첫 번째 상수를 가리킨다(인덱스 값 0은 유효하지 않음).[6]
파일 형식 개발 과정에서 이루어진 역사적 선택으로 인해, 상수 풀 테이블의 상수 수는 실제 개수와 다르다.[6] 테이블은 1부터 시작하여 인덱싱되지만, 개수는 (최대 인덱스 + 1)로 해석해야 한다.[6] 또한, long 및 double 타입의 상수는 테이블에서 두 개의 연속된 슬롯을 차지하지만, 두 번째 슬롯은 직접 사용되지 않는다.[6]
5. 1. 상수 타입 및 태그
상수 풀의 각 항목(상수) 유형은 첫 바이트인 '태그'로 식별된다.[6] 이 태그 뒤에 오는 바이트 수와 그 해석은 태그 값에 따라 달라진다. 유효한 상수 유형과 해당 태그 값은 다음과 같다.
태그 바이트
추가 바이트
상수 설명
도입 버전
1
2+x 바이트 (가변)
UTF-8(유니코드) 문자열: 16비트 숫자(u2 타입)로 시작하는 문자열. 이 숫자는 바로 뒤에 오는 인코딩된 문자열의 바이트 수를 나타낸다(문자 수와 다를 수 있음). 사용된 인코딩은 실제 UTF-8이 아니며 유니코드 표준 인코딩 형식을 약간 수정했다.
Long: 부호 있는 64비트 2의 보수 숫자로, 빅 엔디안 형식(상수 풀 테이블에서 두 개의 슬롯을 차지함)
1.0.2
6
8 바이트
Double: 64비트 배정밀도 IEEE 754 부동 소수점 숫자(상수 풀 테이블에서 두 개의 슬롯을 차지함)
1.0.2
7
2 바이트
클래스 참조: 완전한 클래스 이름(내부 형식)을 포함하는 UTF-8 문자열에 대한 상수 풀 내의 인덱스(빅 엔디안)
1.0.2
8
2 바이트
문자열 참조: UTF-8 문자열에 대한 상수 풀 내의 인덱스(빅 엔디안)
1.0.2
9
4 바이트
필드 참조: 상수 풀 내의 두 인덱스, 첫 번째는 클래스 참조를 가리키고, 두 번째는 이름 및 타입 설명자를 가리킴(빅 엔디안)
1.0.2
10
4 바이트
메서드 참조: 상수 풀 내의 두 인덱스, 첫 번째는 클래스 참조를 가리키고, 두 번째는 이름 및 타입 설명자를 가리킴(빅 엔디안)
1.0.2
11
4 바이트
인터페이스 메서드 참조: 상수 풀 내의 두 인덱스, 첫 번째는 클래스 참조를 가리키고, 두 번째는 이름 및 타입 설명자를 가리킴(빅 엔디안)
1.0.2
12
4 바이트
이름 및 타입 설명자: 상수 풀 내의 UTF-8 문자열에 대한 두 인덱스, 첫 번째는 이름(식별자)을 나타내고 두 번째는 특별히 인코딩된 타입 설명자를 나타낸다.
1.0.2
15
3 바이트
메서드 핸들: 이 구조는 메서드 핸들을 나타내는 데 사용되며, 타입 설명자 1바이트와 상수 풀 내의 인덱스로 구성된다.[6]
7
16
2 바이트
메서드 타입: 이 구조는 메서드 타입을 나타내는 데 사용되며, 상수 풀 내의 인덱스로 구성된다.[6]
7
17
4 바이트
동적: 부트스트랩 메서드 호출에 의해 생성된 동적으로 계산된 상수를 지정하는 데 사용된다.[6]
11
18
4 바이트
InvokeDynamic: invokedynamic 명령에 의해 부트스트랩 메서드, 동적 호출 이름, 호출의 인수 및 반환 유형, 그리고 선택적으로 부트스트랩 메서드에 대한 정적 인수로 불리는 추가 상수 시퀀스를 지정하는 데 사용된다.[6]
7
19
2 바이트
모듈: 모듈을 식별하는 데 사용된다.[6]
9
20
2 바이트
패키지: 모듈에서 내보내거나 열린 패키지를 식별하는 데 사용된다.[6]
9
정수 상수 타입은 정수와 long 두 가지뿐이다. boolean, byte, short와 같이 상위 레벨 언어에 나타나는 다른 정수 타입은 정수 상수로 표현되어야 한다.
Java의 클래스 이름은 완전한 형태로 지정될 때 전통적으로 "java.lang.Object"와 같이 점으로 구분된다. 그러나 하위 레벨 클래스 참조 상수 내에서는 "java/lang/Object"와 같이 슬래시를 사용하는 내부 형식이 나타난다.
"UTF-8 문자열"이라는 명칭에도 불구하고, 유니코드 문자열은 실제로는 유니코드 표준에 따라 인코딩되지 않지만 유사하다. 두 가지 차이점이 있는데, (전체 논의는 UTF-8 참조) 첫 번째는 코드 포인트 U+0000이 표준 단일 바이트 인코딩 `00` 대신 2바이트 시퀀스 `C0 80`(16진수)으로 인코딩된다는 것이다. 두 번째 차이점은 보충 문자(U+10000 이상에서 BMP 외부의 문자)가 UTF-16과 유사한 서러게이트 쌍 구조를 사용하여 인코딩된다는 것이다. 이 경우 두 서러게이트 각각은 UTF-8로 개별적으로 인코딩된다. 예를 들어, U+1D11E는 올바른 4바이트 UTF-8 인코딩 `F0 9D 84 9E` 대신 6바이트 시퀀스 ED A0 B4 ED B4 9E로 인코딩된다.
6. 추가 문헌
팀 린드홀름, 프랭크 옐린, ''The Java Virtual Machine Specification'', 2판 (프렌티스 홀, 1999년), ISBN 0-201-43294-3. JVM 및 클래스 파일 형식을 정의하는 공식 문서이다. 이 책의 초판과 2판 모두 [https://docs.oracle.com/javase/specs/ 온라인에서 무료로 열람 및 다운로드]할 수 있다.
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.