ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10) //OK.
list.add("20") //ERROR
//타입 체크가 강화됨. 지네릭스 덕분에
1.타입 안정성을 제공
2.타입체크와 형변환을 생략할 수 있으므로 코드가 간결해진다.
(ClassCastException 형변환에러를 줄일 수 있다)
(어떻게 하면 런타입에러를 컴파일타임에러로 끌어올 수 있을까?)
ArrayList<Tv> tvList = new ArrayList<Tv>();
Box : 지네릭 클래스. 'T의 Box' 또는 'T Box'라고 읽는다.
T : 타입 변수 또는 타입 매개변수.(T는 타입 문자)
Box : 원시 타입(raw type)
ArrayList<Tv> = new ArrayList<Tv>(); //OK. 일치
ArrayList<Product> = new ArrayList<Tv>(); //에러. 불일
List<Tv> list = new ArrayList<Tv>(); //OK. 다형성
List<Tv> list = new LinkedList<Tv>(); //OK. 다형성
ArrayList<Product> = new ArrayList<Product>();
list.add(new Product());
list.add(new Tv()); //자손도 OK
list.add(new Audio()); //자손도 OK
HashMap<String, Student> map = new HashMap<String, Student>(); //생성
map.put("자바왕", new Student("자바왕",1,1,100,100,100)); //데이터 저장
class FruitBox<T extends Fruit> {
ArryaList<T> list = new ArrayList<T>();
...
} //Fruit의 자손만 대입 가능
FruitBox<Apple> appleBox = new FruitBox<Apple>(); //OK.
FruitBox<Toy> toyBox = new FruitBox<Toy>(); //에러. Toy는 Fruit의 자손이 아님
'<? extends T>' : T와 그 자손들만 가능
'<? super T>' : T와 그 조상들만 가능
'<?>' : 제한 없음. <? extends Object>와 동일
ArrayList<? extends Product> list = new ArrayList<Tv>(); //OK
ArrayList<? extends Product> list = new ArrayList<Audio>(); //OK
static Juice makeJuice(FruitBox<? extends Fruit> box) {
String tmp="";
...
System.out.println(Juicer.makeJuice(new FruitBox<Fruit>()));
System.out.println(Juicer.makeJuice(new FruitBox<Apple>()));
}
지네릭 타입이 선언된 메서드(타입 변수는 메서드 내에서만 유효)
클래스의 타입 매개변수와 메서드의 타입 매개변수 는 별개
class FruitBox<T> {
...
static <T> void sort(List<T> list, Comparator<? super T> c) {
...
}
}
열거형을 정의하는 방법
enum 열거형이름 { 상수명1, 상수명2, ...}
//0, 1 ...
열거형 타입의 변수를 선언하고 사용하는 방법
열거형 상수의 비교에 ==와 compareTo() 사용가능
(비교연산자 사용불가)
Class<E> getDeclaringClass() //열거형의 Class객체를 반환
String name() //열거형 상수의 이름을 문자열로 반환
int ordinal() //열거형 상수가 정의된 순서를 반환(0부터 시작)
T valueOf(Class<T> enumType, String name)
//지정된 열거형에서 name과 일치하는 열거형 상수를 반환
불연속적인 열거형 상수의 경우, 원하는 값을 괄호()안에 적는다.
enum Direction { EAST(1), SOUTH(5), WEST(-1), NORTH(10) }
괄호()를 사용하려면, 인스턴스 변수와 생성자를 새로 추가해 줘야 한다.
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;}
}
Direction d = new Direction(1); //에러. 열거형의 생성자는 외부에서 호출불가
@Test //이 메서드가 테스트 대상임을 테스트 프로그램에 알린다.
public void method() {
...
}
@Deprecated
public int getDate() {
return normalize().getDayOfMonth();
}
컴파일러의 경고메세지가 나타나지 않게 억제한다.
괄호()안에 억제하고자 하는 경고의 종류를 문자열로 지정
둘 이상의 경고를 동시에 억제 가능
'-Xlint' 옵션으로 컴파일하면, 경고메세지를 확인할 수 있다.
SOURCE : 소스 파일에만 존재. 클래스파일에는 존재하지 않음.
CLASS : 클래스 파일에 존재. 실행시 사용불가. 기본값
RUNTIME : 클래스 파일에 존재. 실행시에 사용가능.
javadoc으로 작성한 문서에 포함시키려면 @Documented를 붙인다.
애너테이션을 자손 클래스에 상속하고자 할 때, @Inherited를 붙인다.
@interface 애너테이션이름 {
타입 요소이름(); //애너테이션의 요소를 선언
...
}
적용시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(null제외)
요소가 하나이고 이름이 value일 때는 요소의 이름 생략가능
요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다.
- 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용됨
- 괄호()안에 매개변수를 선언할 수 없다.
- 예외를 선언할 수 없다.
- 요소를 타입 매개변수로 정의할 수 없다.