지네릭 타입의 형변환
- 지네릭 타입과, 논지네릭 타입의 형변환은 가능 ( 경고 발생 )
- 지네릭 타입끼리 형변환 불가
- <String>이 <? extends Object>로 형변환 가능 ( 와일드카드 )
-> 타입이 지정된 지네릭 타입끼리는 형변환이 불가하지만 와일드 카드가 포함된 지네릭 타입으로 형변환은 가능
( 확인 되지 않은 타입으로의 형변환이라는 경고 발생 )
ex)
Optional<Object> -> Optional<T>, 형변환 불가
Optional<?> -> Optional<T>, 형변환 가능
지네릭 타입의 제거
- 컴파일러는 지네릭 타입을 이용해 소스파일 체크 후 필요한 곳에 형변환을 넣어주고 지네릭 타입을 제거
-> 컴파일된 파일(.class)에는 지네릭 타입에 대한 정보x, 지네릭 도입 이전의 소스 코드와의 호환성 유지위함
지네릭 타입의 제거 과정은 복잡해서 기본적인 제거과정에 대해서만 살펴본다
1. 지네릭 타입의 경계(bound)제거
|
1
2
3
4
5
|
class Box<T extends Fruit> {
void add(T t) {
}
}
|
cs |
↓
|
1
2
3
4
5
|
class Box {
void add(Fruit t) {
}
}
|
cs |
2. 지네릭 타입을 제거한 후, 타입이 일치하지 않으면 형변환 추가
|
1
2
3
|
T get(int i) {
return list.get(i);
}
|
cs |
↓
|
1
2
3
|
Fruit get(int i) {
return (Fruit)list.get(i);
}
|
cs |
와일드 카드가 포함되어 있는 경우
|
1
2
3
4
5
6
|
static Juice makeJuice(FruitBox<? extends Fruit> box) {
String tmp ="";
for(Fruit f : box.getList())
tmp += f + " ";
return new Juice(tmp);
}
|
cs |
↓
|
1
2
3
4
5
6
7
8
|
static Juice makeJuice(FruitBox box) {
String tmp ="";
Iterator it = box.getList().iterator();
while(it.hasNext()) {
tmp += (Fruit)it.next() + " ";
}
return new Juice(tmp);
}
|
cs |
열거형
- 서로 관련된 상수를 편리하게 선언하기 위한 것, 여러 상수를 정의할 때 사용하면 유용
- 열거형 상수를 사용하면 기존의 소스를 다시 컴파일하지 않아도 됨
( 기존엔 상수의 값이 바뀌면, 해당 상수를 참조하는 모든 소스를 다시 컴파일해야 했음 )
열거형 정의와 사용
- 괄호{}안에 상수의 이름을 나열
ex)
enum Direction { EAST, SOUTH, WEST, NORTH }
- 열거형에 정의된 상수를 사용하는 방법은 '열거형이름.상수명' ( switch-case문에는 상수명만 사용 )
- 열거형 상수간의 비교에는 '=='를 사용가능, '<', '>'와 같은 비교연산자는 사용 불가 ( compareTo()는 사용가능 )
모든 열겨형의 조상 - java.lang.Enum
- values() : 열겨형의 모든 상수를 배열에 담아 반환
- ordinal() : 열겨형 상수가 정의된 순서(0부터 시작)를 정수로 반환
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
// 열거형 정의
enum Direction { EAST, SOUTH, WEST, NORTH }
public 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)); // equals()메소드 이용해 비교
// System.out.println("d1 > 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 : // switch-case문에서는 상수명만 사용가능
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) {
System.out.printf("%s=%d\n", d.name(), d.ordinal()); // 열거형 상수 이름과, 정의된 순서를 반환
}
}
}
|
cs |
출력
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
'아카이브 > 자바의 정석' 카테고리의 다른 글
| 12장 지네릭스,열거형,애노테이션 20201116 (0) | 2020.11.16 |
|---|---|
| 12장 지네릭스,열거형,애노테이션 20201113 (0) | 2020.11.13 |
| 12장 지네릭스,열거형,애노테이션 20201111 (0) | 2020.11.11 |
| 12장 지네릭스,열거형,애노테이션 20201110 (0) | 2020.11.10 |
| 11장 컬렉션프레임워크 20201109 (0) | 2020.11.09 |