지네릭스, 열거형, 애너테이션 2

LeeKyoungChang·2022년 3월 6일
0
post-thumbnail

Java의 정석 의 책을 읽고 정리한 내용입니다.

 

📚 2. 열거형(enums)

📖 A. 열거형이란?

  • 열거형 : 서로 관련된 상수를 편리하게 선언하기 위한 것으로 여러 상수를 정의할 때 사용하면 유용하다.
  • 자바의 열거형은 타입에 안전한 열거형이라서 실제 값이 같아도 타입이 다르면 컴파일 에러가 발생한다.
  • 열거형은 값뿐만 아니라 타입까지 체크하기 때문에 타입에 안전하다고 하는 것이다.
  • 열거형 상수를 사용하면, 기존의 소스를 다시 컴파일하지 않아도 된다.

 

📖 B. 열거형의 정의와 사용

enum 열거형 이름 { 상수명1, 상수명2, ... }
  • 열거형에 정의된 상수 사용 방법 : 열거형이름.상수명
  • 열거형 상수간의 비교에는 ==를 사용할 수 있다.
  • 그러나 <, >'와 같은 비교 연산자는 사용할 수 없고 compareTo()는 사용할 수 있다.
if (idr == Direction,EAST {
	x++;
} else if (dir > Direction.WEST) { // 에러 열거형 상수에 비교연산자는 사용 불가능
	...
} else if (dir.compareTo(Direction.WEST) > 0) // compareTo()는 가능
	...
}
  • compareTo()는 두 비교대상이 같으면 0, 왼쪽이 크면 양수, 오른쪽이 크면 음수를 반환한다.

 

✔️ 모든 열거형의 조상 - java.lang.Enum

Direction[] dArr = Direction.values();
for(Direction d : dArr) // for(Direction d : Direction.values())
	System.out.printf("%s=%d%n", d.name(), d.ordinal());
  • 열거형 Direction에 정의된 모든 상수를 출력한다.
  • values()는 열거형의 모든 상수를 배열에 담아서 반환한다.

 

메서드설명
Class<E>getDeclaringClass()열거형의 Class객체를 반환한다.
String name()열거형 상수의 이름을 문자열로 반환한다.
int ordinal()열거형 상수가 정의된 순서를 반환한다.(0부터 시작)
T valueOf(Class<T>enumType, String name)지정된 열거형에서 name과 일치하는 열거형 상수를 반환한다.

valueOf는 열거형 상수의 이름으로 문자열 상수에 대한 참조를 얻을 수 있게 해준다.

Direction d = Direction.valueOf("WESET");

System.out.println(d); // WEST
System.out.println(Direction.WEST == Direction.valueOf("WEST"); // true

 

enum Direction { EAST, SOUTH, WEST, NORTH }

class EnumEx1 {
	public static void main(String[] args) {
		Direction d1 = Direction.EAST;
		Direction d2 = Direction.valueOf("WEST");
		Direction d3 = Enum.valueOf(Direction.class, "EAST");

		System.out.println("d1="+d1);
		System.out.println("d2="+d2);
		System.out.println("d3="+d3);

		System.out.println("d1==d2 ? "+ (d1==d2));
		System.out.println("d1==d3 ? "+ (d1==d3));
		System.out.println("d1.equals(d3) ? "+ d1.equals(d3));
//		System.out.println("d2 > d3 ? "+ (d1 > d3)); //에러
		System.out.println("d1.compareTo(d3) ? "+ (d1.compareTo(d3)));
		System.out.println("d1.compareTo(d2) ? "+ (d1.compareTo(d2)));

		switch(d1) {
			case EAST: // Direction.EAST¶ó°í ¾µ ¼ö ¾ø´Ù.
				System.out.println("The direction is EAST."); 
				break;
			case SOUTH:
				System.out.println("The direction is SOUTH."); 
				break;
			case WEST:
				System.out.println("The direction is WEST."); 
				break;
			case NORTH:
				System.out.println("The direction is NORTH."); 
				break;
			default:
				System.out.println("Invalid direction."); 
			break;
		}

		Direction[] dArr = Direction.values();

		for(Direction d : dArr)  // for(Direction d : Direction.values()) 
			System.out.printf("%s=%d%n", d.name(), d.ordinal()); 
	}
}
d1=EAST
d2=WEST
d3=EAST
d1==d2 ? false
d1==d3 ? true
d1.equals(d3) ? true
d1.compareTo(d3) ? 0
d1.compareTo(d2) ? -2
The direction is EAST.
EAST=0
SOUTH=1
WEST=2
NORTH=3

&nbps;
&nbps;

📖 C. 열거형에 멤버 추가하기

enum Direction { EAST(1), SOUSTH(5), WEST(-1), NORTH(10) }
  • 열거형 상수의 값이 불연속적인 경우에는 이때는 열거형 상수의 이름 옆에 원하는 값을 괄호()와 함게 적어주면 된다.

 

enum Direction {
	EAST(1), SOUSTH(5), WEST(-1), NORTH(10); // 끝에 ';'를 추가해야 한다.
    private final int value; // 정수를 저장할 필드(인스턴스 변수)를 추가
    Direction(int value) { thi.value=value; } // 생성자를 추가
    public int getValue() { return value; }
}
  • 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자를 새로 추가해 주어야 한다.
  • 열거형 상수의 마지막에 ;도 잊지 말아야 한다.
  • 열거형의 인스턴스 변수는 반드시 final이어야 한다는 제약은 없지만, value는 열거형 상수의 값을 저장하기 위한 것이므로 final을 붙였다.
  • 그리고 외부에서 이 값을 얻을 수 있도록 getValue()도 추가했다.

 

Direction d = new Direction(1); // 에러 열거형의 생성자는 외부에서 호출불가
  • 열거형 Direction에 새로운 생성자가 추가되었지만, 열거형의 객체를 생성할 수 없다.
  • 열거형의 생성자는 제어자가 묵시적으로 private이기 때문이다.
enum Direction {
		...
   Direction(int value) { // private Direction(int value)와 동일하다
   	...
}

 

✔️ 열거형에 추상 메서드 추가하기

enum TRansportation {
	BUS(100), TRAIN(150), SHIP(100), AIRPLANE(300);
    
    private final int BASIC_FARE;
    private TRansportation(int basicFare) {
    	BASEIC_FARE = basicFare;
    }
    int fare() { // 운송 요금을 반환한다
    	return BASIC_FARE;
    }
}
  • 열거형에 추상 메서드 fare(int distance)를 선언하면 각 열거형 상수가 이 추상 메서드를 반드시 구현해야 한다.
enum TRansportation {
	BUS(100) {
    	int fare(int distance) { return distance*BASIC_FARE;}
   	},
    TRAIN(15) { int fare(int distance) { return distance*BASIC_FARE;}},
    SHIP(100) { int fare(int distance) { return distance*BASIC_FARE;}},
    AIRPLANE(300) { int fare(int distance) { return distance*BASIC_FARE;}},
    
    abstract int fare(int distance); // 거리에 따른 요금을 계산하는 추상 메서드
    protected final int BASIC_FARE; // protected로 해야 각 상수에서 접근 가능
    Transportation(int basicFare) {
    	BASIC_FARE = basicFare;
    }
    public int getBasicFare() { return BASIC_FARE; }
}

 

📖 D. 열거형의 이해

열거형 Direction이 정의되어 있을 때

enum Direction { EAST, SOUTH, WEST, NORTH }
  • 열거형 상수 하나하나가 Direction객체다.

 

abstract class MyEnum<T extends  MyEnum<T>> implements Comparable<T>{
    static int id = 0;
    int oridinal;
    String name = "";

    public int oridinal(){ return oridinal; }

    MyEnum(String name){
        this.name = name;
        oridinal = id++;
    }

    public int compareTo(T t){
        return oridinal - t.oridinal();
    }
}

abstract class MyTransportation extends MyEnum {
   static final MyTransportation BUS = new MyTransportation("BUS", 100) {
       int fare(int distance) { return distance - BASIC_FARE; }
   };
    static final MyTransportation TRAIN = new MyTransportation("TRAIN", 150) {
        int fare(int distance) { return distance - BASIC_FARE; }
    };
    static final MyTransportation SHIP = new MyTransportation("SHIP", 100) {
        int fare(int distance) { return distance - BASIC_FARE; }
    };
    static final MyTransportation AIRPLANE = new MyTransportation("AIRPLANE", 300) {
        int fare(int distance) { return distance - BASIC_FARE; }
    };

    abstract int fare(int distance); // 거리에 따른 요금을 계산하는 추상 메서드
    protected final int BASIC_FARE; // protected로 해야 각 상수에서 접근 가능
    private MyTransportation(String name, int basicFare){
        super(name);
        BASIC_FARE = basicFare;
    }

    public String name() { return name; }
    public String toString() { return name; }

}

public class EnumEx4 {
    public static void main(String[] args) {
        MyTransportation t1 = MyTransportation.BUS;
        MyTransportation t2 = MyTransportation.BUS;
        MyTransportation t3 = MyTransportation.SHIP;
        MyTransportation t4 = MyTransportation.AIRPLANE;
        MyTransportation t5 = MyTransportation.AIRPLANE;

        System.out.printf("t1=%s, %d%n", t1.name(), t1.oridinal());
        System.out.printf("t2=%s, %d%n", t2.name(), t2.oridinal());
        System.out.printf("t3=%s, %d%n", t3.name(), t3.oridinal());
        System.out.printf("t4=%s, %d%n", t4.name(), t4.oridinal());
        System.out.printf("t5=%s, %d%n", t5.name(), t5.oridinal());
        System.out.println("t1==t2 ? "+ (t1==t2));
        System.out.println("t1.compareTo(t3)="+ t1.compareTo(t3));
    }
}
t1=BUS, 0
t2=BUS, 0
t3=TRAIN, 1
t4=SHIP, 2
t5=AIRPLANE, 3
t1==t2 ? true
t1.compareTo(t3)=-1

 

profile
"야, (오류 만났어?) 너두 (해결) 할 수 있어"

0개의 댓글

관련 채용 정보