자바의 정석 12장 지네릭스, 열거형, 애너테이션
관련된 상수를 같이 묶어놓은 것
열거형의 정의와 사용
java.lang.Enum 클래스 (693p)
열거형에 멤버 추가하기 (695p)
열거형의 생성자는 묵시적으로 private, 외부에서 호출 불가
예시
enum Direction {
EAST(1), SOUTH(5), WEST(-1), NORTH(10);
private final int value;
Direction (int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
예제
public class EnumEx2 {
public static void main(String[] args) {
for (Direction d : Direction.values()) {
System.out.printf("%s=%d%n", d.name(), d.getValue());
}
Direction d1 = Direction.EAST;
Direction d2 = Direction.of(1);
System.out.printf("%s : %d%n", d1.name(), d1.getValue());
System.out.printf("%s : %d%n", d2.name(), d2.getValue());
System.out.println(Direction.EAST.rotate(1));
}
}
enum Direction {
EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
private static final Direction[] DIR_ARR = Direction.values();
private final int value;
private final String symbol;
Direction(int value, String symbol) {
this.value = value;
this.symbol = symbol;
}
public int getValue() {
return value;
}
public String getSymbol() {
return symbol;
}
public static Direction of(int dir) {
if (dir < 1 || dir > 4) {
throw new IllegalArgumentException("Invalid value :" + dir);
}
return DIR_ARR[dir - 1];
}
// 방향을 회전시키는 메서드. num의 값만큼 90도씩 시계방향으로 회전한다.
public Direction rotate(int num) {
num = num % 4;
if (num < 0) {
num += 4; // num이 음수일때는 시계반대 방향으로 회전
}
return DIR_ARR[(value - 1 + num) % 4];
}
}
미션3 코드 수정 후 피드백 내용
enum을 선언할 때는 한줄에 하나씩 선언한다.
public enum Color {
WHITE('p'),
BLACK('P');
...
}
JVM이란
자바 어플리케이션은 JVM하고만 상호작용해서 OS와 하드웨어에 독립적이다.
→ 다른 OS에서도 실행 가능
단, JVM은 운영체제에 종속적이여서 해당 OS에서 실행 가능한 JVM이 필요하다.
Java byte코드로 컴파일될 수 있는 다른 언어도 실행가능
JDK와 JRE
JDK의 bin 디렉토리에 있는 주요 실행 파일들
호눅스 수업과 아래의 두 블로그를 참고하여 내용정리함
The JVM Architecture Explained - DZone Java
자바 프로그램을 실행하면
JVM은 세가지의 subsystem(부분 시스템)으로 이루어짐
Class Loader Subsystem
(1) Bootstrap Class Loader
가장 높은 우선순위가 부여되는 loader, 최상위 클래스 로더이다.
rt.jar에 담긴 JDK클래스 파일을 로딩한다.
rt.jar 파일이란?
rt는 runtime을 의미한다.
rt.jar는 코어 자바클래스(자바 런타임 환경에서)의 콜렉션이다.
JVM에서 rt.jar파일에 담긴 플래스파일들을 런타임시 메모리에 올린다. String 클래스, System 클래스와 같은 것들이 rt.jar에 포함되어 있다.
(2) Extension Class Loader
(3) Application Class Loader
Runtime Data Area
Execution Engine
바이트 코드는 어디에 저장되나?
정적 변수는 어디에, 언제 저장되나?
인스턴스 변수는 어디에 저장되나?
JVM이 동작하는 것을 학습하기 위한 예제 - 코드의 실행순서를 예측해보자
public class Hello {
public static int age = 25;
static {
System.out.println("static!");
}
public Hello(){
System.out.println("Hello init");
}
public static void main(String[] args) {
System.out.println("Hello");
}
}
</> 실행 결과
static!
Hello
Hello.java파일을 실행하면 컴파일러가 Hello.class파일로 컴파일 하고
→ Hello.class 파일이 JVM에 올라가고
→ class loader가 클래스 파일을 메모리에 로드하고
→ Liking : 이때, static 변수 age가 기본값으로 저장됨 (age = 0)
→ initialization : age가 초기값으로 저장됨(age = 25), static block 실행 ( static! 출력)
→ Hello 출력
생성자는 객체를 생성할때 실행되므로 위의 상황에서는 실행되지 않는다.
아래의 예시는 class loader가 동적으로 클래스파일을 로딩한다는 것을 추가로 보여준다.
public class Hello {
public static int age = 25;
static {
System.out.println("static!");
}
public Hello() {
System.out.println("Hello init");
}
public static void main(String[] args) {
Hello h = new Hello();
System.out.println("Hello");
Hell.foo();
}
}
class Hell {
static {
System.out.println("static hell");
}
static void foo() {
System.out.println("foo");
}
}
</> 실행 결과
static!
Hello init
Hello
static hell
foo
Hello의 static 블록 먼저 출력 (static!)
→ Hello h = new Hello(); 로 객체 생성해서 생성자 호출 (Hello init 출력)
→ Hello 출력
→ Hell의 static 블록 출력 (클래스 로더가 처음부터 모든 클래스를 로드하지 않고 필요할때마다 동적으로 로드한다.)
static hell 출력
→ foo() 메소드 호출(foo 출력)
rotate : 회전하다(시키다)
convert : 전환시키다
corresponding : ~에 해당(상응)하는)
java.exe : 자바 컴파일러, 자바 소스코드를 바이트 코드로 컴파일한다.
java.exe : 자바 인터프리터, 컴파일러가 생성한 바이트 코드를 해석하고 실행한다.
오타 발견! ㅋㅋㅋ