컴파일타임? 아래와 같이 3가지로 설명될 수 있음:
이번 장은 그 중 1번.
이전 6, 7, 8, 9장에서 설명되었던 런타임단계의 클래스 로딩, 링킹, 초기화, 스프링 컨테이너 빈 생성, 의존관계 주입 등 class파일을 JVM 메모리에 올리고 객체를 Container 등록하는 과정 전에 일어나는 빌드 타임 작업에 대한 설명을 할 거란 말. 톰캣 올리기 전 끝나있는 class 파일 만드는 "컴파일"에 대해 설명하는 장임.
최적화 또한 다음과 같이 정의한다:
javac와 같은 프런트엔드 컴파일러는 코드 실행 효율 측면의 최적화는 거의 하지 않으며, JDK 1.3 이후로는 성능 최적화를 런타임 컴파일러에 집중시켰다.
(그루비 클래스 파일 등도 최적화 효과를 공평하게 누리기 위해)
개발단계까지 최적화를 넓혀 부른다면,
런타임: 실행 효율을 높이는 최적화를 JIT 컴파일러에서 지속해서 수행
컴파일타임: 개발자 코딩 효율 높이는 최적화를 프런트엔드 컴파일러가 수행
10.2 javac 컴파일러

Java소스파일을 클래스 파일로 컴파일 하는 방법은 아주 느슨하게 설명되어있어 자유도가 높음
장점: 자바 프런트엔드 컴파일러의 자유도 vs 단점:컴파일 과정이 특정 JDK 또는 컴파일러 구현에 따라 달라지는 경우도 생김
javac 코드의 전체 구조 확인을 통한 컴파일 처리 단계: 1단계 준비 + 3단계 처리
0: 플러그인 annotation 처리기 초기화
1: 구문 분석 및 심벌 테이블 채우기(소스 코드 토큰화하여 추상 구문 트리 구성/심벌 주소와 심벌 정보 생성)
2: 플러그인 annotation 처리기들로 annotation 처리
3: 의미분석 및 바이트코드 생성(특성검사를 통한 문법의 정적 정보 확인/데이터 흐름 및 제어 흐름 분석을 통한 프로그램의 동적 실행 과정 확인/편의문법 제거하여 원래 형식으로 복원/바이트 코드 생성)
compile 도중에 플러그인 annotation 실행 시, 새로운 심벌 생성될 수 있음.
그럼 이 새 심벌 다시 처리하려고 심벌 테이블 채우던 때로 돌아가야 함
그 상호작용순서는 아래와 같음:

javac의 컴파일 과정 맡은 클래스: com.sun.tools.javac.main.JavaCompiler
앞선 3단계 처리는 compile() method에 집중되어있음
javac 소스코드 기준으로 3단계 처리 과정 항목별 설명:

1: 구문분석 및 심벌 테이블 채우기
구문분석:
심벌 테이블 채우기:
2: 애너테이션 처리
3: 의미 분석과 바이트코드 생성
1) 특성 검사: 변수를 사용하기 앞서 선언이 되어 있는지, 변수와 할당될 데이터의 타입이 일치하는지 등을 확인 / 접기(constant folding)라는 최적화도 수행
2) 데이터와 제어 흐름 분석: 프로그램이 맥락상 논리적으로 올바른지 확인. 기본적으로 클래스 로딩 시 수행하는 데이터 및 제어 흐름 분석의 목적과 같음 BUT 검증 범위가 다르기 때문에 항목에 따라 컴파일 타임에만 수행되거나 런타임에만 수행되기도 함
(ex. 지역변수는 상수 풀에 대한 심벌 참조가 없어 접근 플래그 정보 저장 못되므로, final이 붙어도 런타임에는 아무 영향이 없음. so, 오직 컴파일타임에 javac 컴파일러에서만 보장, 검사되는 대표적 예시)
JAVA 편의문법:
Generic, 오토박싱/언박싱, 개선된 for문, 가변 길이 매개 변수, 조건부 컴파일 등(C#과 비교하여 코드 트렌드를 따르는 다양한 편의 문법의 예시와 역사, 사용법)
실전: 플러그인 애너테이션 처리기 제작