읽기 전
- 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다.
- 개인적으로 사용해보면서 배운 점을 정리한 글입니다.
문제 제기
자바를 공부하던 중 왜 메소드를 클래스 안에 넣어야만 하는가에 대해 궁금했다. 내용을 찾던 중 javac compiler가 .java 파일을 .class 파일로 변환하는 과정에 기인함을 알게되었고 겸사겸사 Java의 .class 파일 구조에 대해 작성하고자 한다.
java 코드에서 메소드가 클래스에 속해야 하는 이유
java 코드를 javac compiler로 컴파일할 때 컴파일러는 java 코드 내 class 블록을 찾아서 각각의 .class 파일로 구분하여 byte코드를 생성한다. 즉, 메소드가 class 블록 내에 있지 않으면 해당 메소드에 대한 상위 클래스를 찾을 수 없어 컴파일 에러가 발생한다.
위 그림과 같이 한 소스 파일 내 여러 클래스 정의 후 컴파일 수행 시 코드에 정의한 class 개수만큼 .class 파일이 생성됨을 알 수 있다.
java .class 파일 구조
- magic_number : JVM이 valid한 compiler로부터 .class 파일이 생성되었는지 검증하는 값
- major_version & minor_version : .class 파일의 컴파일 버전을 의미한다. 낮은 버전의 컴파일러에서 생성된 .class 파일은 상위 버전에 JVM에서 구동할 수 있으나 그 반대는 runtime exception을 출력하여 구동이 불가하다.
- .class 파일을 생성한 javac 컴파일러 버전 <= JVM 버전이어야 구동이 가능
- constant_pool_count : .java 파일 컴파일 시 모든 변수와 메소드 참조 주소는 constant pool에 symbolic reference로 저장된다.
- constant_pool[] : 변수, 메소드 정보를 담은 symbolic reference 배열
- symbolic reference : 클래스의 특정 메모리 주소를 참조 관계가 아니라 참조하는 대상의 이름만을 지칭
- 이름에 맞는 객체의 주소를 찾아서 연결하므로 실제 메모리 주소가 아니라 이름만을 갖게되는 것
- access_flag : class file에 선언된 제어자 정보
- this_class : class file의 정보
- super_class : 현재 클래스의 상위 클래스(extend한 클래스)를 의미 (없으면 Object가 상위)
- interface_count : 현재 class file이 implements한 interface 개수
- interface[] : implements한 interface들의 정보를 담은 배열
- fields_count : 현재 class file에 선언된 static 변수(클래스 변수) 개수
- fields[] : 클래스 변수 정보를 담은 배열
- method_count : 현재 class file에 선언된 메소드 개수
- method[] : 선언된 메소드 정보를 담은 배열
- attributes_count : 현재 class file에 선언된 변수(인스턴스 변수) 개수
- attributes[] : 인스턴스 변수 정보를 담은 배열
'Development > Java' 카테고리의 다른 글
Java 명령어 실행 시 파일 확장자를 제거하는 이유 (0) | 2021.10.21 |
---|---|
Java float, double, BigDecimal - 부동소수점 오차 (2) | 2021.10.21 |
Java 객체와 변수 데이터의 저장 (0) | 2021.10.21 |
Java 런타임 데이터 영역 (8) | 2021.10.21 |
Java 컴파일 및 런타임 환경 구조 (0) | 2021.10.21 |