[리뷰] 처음 해보는 자바 프로그래밍 - 13. 제너릭과 어노테이션
데이터 타입을 실행할 매개변수(타입 매개변수)로 받아 결정
//어떤게 쓰일줄 몰라 일단 만들었다가
class Text { A a;}
class Text { B b;}
class Text { C c;}
//이렇게 합쳐봤다
class Text { A a; B b; C c; }
// 하지만 Text 클래스 사용 시 한 필드만 쓸거면 안쓰는 필드가 낭비된다
// 그래서 제네릭 클래스로 선언!
public class Text<T> {
T alphabet;
public Text(T alphabet) {
this.alphabet = alphabet;
}
}
//사용할 땐
new Text<A>(new A()); // JDK5
new Text<>(new A()); // JDK7부터 인자 생략 가능(생성자의 인자로 자동 지정)
class Text{
private Object alphabet;
public Text(Object alphabet) {
this.alphabet = alphabet;
}
public Object getAlphabet(){
return alphabet;
}
}
//Object 방식
Text textA = new Text(new A());
A a = (A)textA.getAlphabet(); //Object -> A 로 타입 변경 필요
Text textB = new Text(new B());
Text textC = new Text(new C());
textB = textC //컴파일 시 에러 못잡음
// 제너릭 방식
Text<A> textA = new Text<>(new A());
A a = textA.getAlphabet(); //타입변경 불필요
Text<B> textB = new Text<>(new B());
Text<C> textC = new Text<>(new C());
textB = textC //error!
타입 매개변수 복수 선언 :
Text<B, C> text = new Text<>(new B(), new C());
타입 매개변수 제한 :
class 클래스명 < T extends 상위클래스명>
와일드 카드 :
public class Text<T> {
T alphabet;
int count;
public boolean isSameCountT(Text<T> text>{
return this.count == text.count;
}
public boolean isSameCountWildCard(Text<?> text>{
return this.count == text.count;
}
}
textA.isSameCountT(textB); //error!
textA.isSameCountWildCard(textB); //ok
// 제너릭 메서드 : <타입 매개변수s> 리턴타입 메서드명(매개변수s) { ... }
<T extends Number, V extends T> boolean isInclude(T num, V[] array) {
for(int i = 0; i < array.length; i++) {
if(array[i] == num) {
return true;
}
}
return false;
}
// 제너릭 생성자 : <타입 매개변수s> 클래스명(매개변수s){ ... }
class StrngUtil{
private String value;
<T extends CharSequence> StringUtil(T value){
this.value = value.toString();
}
}
// 제너릭 인터페이스
interface Maximum<T extends Comparable<T>> { ... }
class NumUtil<T extends Comparable<T>> implements Maximum<T> { ... }
컴파일러를 비롯, 개발/배치 등의 도구에 정보를 제공할 목적
자동으로 Annotation 인터페이스를 상속
@Retention(RetentionPolicy.RUNTIME)
@interface Check {
String name();
int val() default 1004;
strinv mode() default "test";
}
@interface Bean {
String value();
}
@Check(name="first", val=123)
@Bean("Member") //value라는 이름의 변수 하나만 있는경우 이렇게 사용가능
public static void test(){ ... }
어노테이션 정보 사용을 위해서는
1) Class 객체 생성 :
. final Class<?> getClass()
. 객체명.class
2) 리플렉션(클래스의 정보 처리, java.lang.reflect) 사용
. Method getMethod(String) : 전달받은 이름을 가진 메서드를 Method 객체로 반환
. boolean isAnnotationPresent(Class) : 전달받은 어노테이션 적용 여부 반환
. Annotation getAnnotation(Class) : 전달받은 어노테이션을 Annotation 객체로 반환
. Annotation[] getAnnotations() : 적용한 모든 어노테이션을 Annotation 객체로 반환
java.lang.annotation 제공
@Retention : 어노테이션의 유지 범위
@Document : 자바 문서 포함 여부
@Target : 어노테이션 적용 대상 - ElementType.XX
@Ingerited : 하위객체에도 해당 어노테이션 적용
java.lang 제공
@Override
@Deprecated : 사용하지 않을 것 권장
@FunctionalInterface : 함수형 인터페이스 (컴파일 시 메서드 1개인지 체크, 안써도 OK)
@SafeVarargs : 가변길이 인자 사용하는 메서드 선언부에 사용시 경고 무시
@SuppressWarning : 컴파일러 경고 무시
이번 장은 피하고 싶던 장이었다. 대충 쓸 수 있는 정도로 알고있었는데 자세하게는 너무 어려워보여서 꼭 알아야 하는게 아니라면 자세히 알고싶지 않은... 그래도 꾹꾹 참고 공부했는데 너무 설명이 잘 되어있어 이해할 수 있었다. 제너릭/어노테이션의 사용법 뿐 아니라 어떻게, 왜 만들어졌는지까지 알려주셔서 정말... 작가님이 계속계속 글을 써주시면 좋겠다.