class Card{
static final int CLOVER = 0;
static final int HEART = 1;
static final int DIAMOND = 2;
static final int SPADE = 3;
static final int TWO = 0;
static final int THREE = 1;
static final int FOUR = 2;
final int kind;
final int num;
}
->
if(Card.CLOVER==Card.TWO) //true
위의 경우, true
지만 false
여야 의미상 맞다.
아래처럼 열거형으로 표현할 수 있다.
class Card{ enum Kind { CLOVER, HEART, DIAMOND, SPADE } //열거형 Kind // 상수의 값이 저절로 0, 1, 2, 3 enum Value { TWO, THREE, FOUR } //열거형 Value // 상수의 값이 저절로 0, 1, 2 final Kind kind; //*****타입이 int가 아닌 Kind!!!!! final Value value; }
->
if(Card.Kind.CLOVER==Card.Value.TWO) //컴파일 에러!!!
타입이 달라서 비교 불가 -> 컴파일 에러!!!
이처럼 자바의 열거형은 값과 타입을 모두 체크한다.
✨✨열거형 상수 각각 객체다!!
enum 열거형이름 { 상수명1, 상수명2, ... }
예)
enum Direction { EAST, SOUTH, WEST, NORTH }
class Unit{
int x, y //유닛의 위치
Direction dir; //열거형 인스턴스 변수를 선언
//***이 dir은 위에서 선언한 {EAST, SOUTH...} 만 들어올 수 있다!!!
void init(){
dir = Direction.EAST; //유닛의 방향을 EAST로 초기화
}
}
==
, compareTo()
사용가능-> 왜?? 객체니까!!!
if(dir==Directoin.EAST) { //true
x++;
} else if(dir > Direction.WEST) { //(X) 에러!! 열거형상수에 비교연산자 사용불가
...
} else if(dir.compareTo(Direction.WEST) > 0) { //음수-> false
...
}
Enum
의 자손이며, 아래의 메소드를 상속받는다.Class<E> getDeclaringClass()
잘 안쓰임..
String name()
int ordinal()
T valueOf(Class<T> enumType, String name)
name
과 일치하는 열거형 상수를 반환static E[] values()
Direction[] dArr = Direction.values();
static E valueOf(String name)
Direction d = Direction.valueOf("WEST");
//아래와 같다
Direction d = Direction.WEST
for(Direction d : dArr) // for(Direction d : Direction.values())
System.out.printf("%s=%d%n", d.name(), d.ordinal()); //이름, 순서 출력
열거형타입.상수이름
Direction d1 = Direction.EAST; -> d1 = EAST
valueOf(상수이름)
Direction d2 = Direction.valueOf("EAST"); -> d2 = EAST
Enum.valueOf(Class<T>, 상수이름)
Direction d3 = Enum.valueOf(Directoin.class, "EAST"); -> d3 = EAST
ex12_05
// 0 1 2 3
enum Direction { EAST, SOUTH, WEST, NORTH }
public class Ex12_05 {
public static void main(String[] args) {
//***열거형 상수를 읽어오는 방법 3가지
Direction d1 = Direction.EAST; //0
Direction d2 = Direction.valueOf("WEST"); //2
Direction d3 = Enum.valueOf(Direction.class, "EAST"); //0
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("d2==d3 ? "+(d2==d3));
// System.out.println("d2 >d3 ? "+(d2>d3)); //에러
System.out.println("d1.equals(d2) ? "+d1.equals(d2));
System.out.println("d1.equals(d3) ? "+d1.equals(d3));
System.out.println("d2.equals(d3) ? "+d2.equals(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 directoin is EAST.");
break;
case SOUTH:
System.out.println("the directoin is SOUTH.");
break;
case WEST:
System.out.println("the directoin is WEST.");
break;
case NORTH:
System.out.println("the directoin is NORTH.");
break;
default:
System.out.println("Invaalid direction.");
break;
}
Direction[] dArr = Direction.values();
//열거형의 모든 상수를 배열로 반환
// System.out.println(dArr); 로 하면 안나온다 ㅋㅋㅋ 잊지마
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
d2==d3 ? false
d1.equals(d2) ? false
d1.equals(d3) ? true
d2.equals(d3) ? false
d1.compareTo(d3) ? 0
d1.compareTo(d2) ? -2
the directoin is EAST.
EAST=0
SOUTH=1
WEST=2
NORTH=3
enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10) }
enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10);
private final int value; //정수를 저장할 필드(iv) 추가
Direction(int value) {
this.value = value; //생성자 추가
}
public int getValue() {
return value;
}
}
- 열거형의 생성자는 묵시적으로 `private`이므로, 외부에서 객체생성 불가
```java
Direction d = new Direction(1); //(X) 열거형의 생성자는 외부에서 호출불가
private final
ivpublic
getIV명()ex12_06
enum Direction2{
EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
private static final Direction2[] DIR_ARR = Direction2.values();
private final int value;
private final String symbol;
Direction2(int value, String symbol) { //private 생략
this.value = value;
this.symbol = symbol;
}
public int getValue() {
return value;
}
public String getSymbol() {
return symbol;
}
//DIR_ARR[dir-1]의 열거형상수를 꺼내오는 메소드
public static Direction2 of(int dir) {
if(dir < 1 || dir > 4) //1~4가 아니면
throw new IllegalArgumentException("Invalid value: "+dir);
return DIR_ARR[dir-1]; //***인덱스는 하나 작으니까!
}
//방향을 회전시키는 메소드. num의 값만큼 90도씩 시계방향으로 회전한다.
public Direction2 rotate(int num) {
num %= 4; //**큰수가 나와도 되게 & 어차피 4방향이니
if(num < 0)
num += 4; //***num이 음수일 때 시계반대방향으로 회전인데, 그게 +4한 것과 같음!
return DIR_ARR[(value-1 + num)% 4];
//***value가 뭔줄 알고 받는거지.....
//아 메소드호출할때 열거형상수를 받는구나
}
public String toString() { return name()+getSymbol();}
}
public class Ex12_06 {
public static void main(String[] args) {
for(Direction2 d : Direction2.values())
System.out.printf("%s = %d%n", d.name(), d.getValue());
//**d.getValue() 는 ordinal()과 다르다!! 값과 인덱스 다르듯이!!
Direction2 d1 = Direction2.EAST;
Direction2 d2 = Direction2.of(1); //DIR_ARR[0]
Direction2 d3 = Direction2.of(2); //DIR_ARR[1]
// Direction2 d4 = Direction2.of(6); //예외발생
System.out.printf("d1 = %s, %d%n", d1.name(), d1.getValue());
System.out.printf("d2 = %s, %d%n", d2.name(), d2.getValue());
System.out.printf("d3 = %s, %d%n", d3.name(), d3.getValue());
//***toString()오버라이딩해서 결과가 저렇지, 안그러면 EAST(name())만 나온다!!
System.out.println(d1);
System.out.println(Direction2.EAST.rotate(1));
//d1.rotate(1) 해도 됨!
System.out.println(d1.rotate(1));
//EAST에서 1번 시계방향으로 회전하라
System.out.println(Direction2.EAST.rotate(2));
System.out.println(Direction2.EAST.rotate(-1));
System.out.println(Direction2.EAST.rotate(-2));
}
}
EAST = 1
SOUTH = 2
WEST = 3
NORTH = 4
d1 = EAST, 1
d2 = EAST, 1
d3 = SOUTH, 2
EAST>
SOUTHV
SOUTHV
WEST<
NORTH^
WEST<