13. 제너릭과 어노테이션

dldngus5·2020년 6월 28일
0
post-thumbnail

[리뷰] 처음 해보는 자바 프로그래밍 - 13. 제너릭과 어노테이션

내용 정리

13.1 제너릭

13.1.1 제너릭 개요

데이터 타입을 실행할 매개변수(타입 매개변수)로 받아 결정

  • 제너릭 클래스 : class 클래스명<타입 매개변수> { ... } = new 클래스명<타입 인자>();
//어떤게 쓰일줄 몰라 일단 만들었다가
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부터 인자 생략 가능(생성자의 인자로 자동 지정)
  • JDK5 이전엔 변수 타입을 Object(모든 클래스의 최상위)로 선언하여 구현
class Text{
	private Object alphabet;
    public Text(Object alphabet) {
    	this.alphabet = alphabet;
    }
    public Object getAlphabet(){
    	return alphabet;
    }
}
  • Object 대신 제너릭을 만든 이유? (제네릭이 가지는 장점?)
    1) 불필요한 타입 변경 X
    2) 컴파일러 검사로 타입 안정성 보장
//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!

13.1.2 타입 매개변수

  • 타입 매개변수 복수 선언 :
    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

13.1.3 다양한 적용

// 제너릭 메서드 : <타입 매개변수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> { ... }

13.2 어노테이션

13.2.1 어노테이션 개요

컴파일러를 비롯, 개발/배치 등의 도구에 정보를 제공할 목적
자동으로 Annotation 인터페이스를 상속

  • 선언 : @interface 어노테이션명 { 데이터타입 변수명() default 값; }
  • 사용 : @어노테이션명(변수명=값, 변수명=값), @어노테이션명(값)
  • 유지 : @Retention(RetentionPolicy.열거상수)
    • SOURCE : 컴파일 시 삭제
    • CLASS : 컴파일 후 유지 but JVM 사용불가
    • RUNTIME : 컴파일 후 유지 and JVM 사용가능
@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(){ ... }

13.2.2 정보 추출

어노테이션 정보 사용을 위해서는
1) Class 객체 생성 :
. final Class<?> getClass()
. 객체명.class
2) 리플렉션(클래스의 정보 처리, java.lang.reflect) 사용
. Method getMethod(String) : 전달받은 이름을 가진 메서드를 Method 객체로 반환
. boolean isAnnotationPresent(Class) : 전달받은 어노테이션 적용 여부 반환
. Annotation getAnnotation(Class) : 전달받은 어노테이션을 Annotation 객체로 반환
. Annotation[] getAnnotations() : 적용한 모든 어노테이션을 Annotation 객체로 반환

13.2.3 기본값 지정

13.2.4 표준 어노테이션

  • java.lang.annotation 제공
    @Retention : 어노테이션의 유지 범위
    @Document : 자바 문서 포함 여부
    @Target : 어노테이션 적용 대상 - ElementType.XX
    @Ingerited : 하위객체에도 해당 어노테이션 적용

  • java.lang 제공
    @Override
    @Deprecated : 사용하지 않을 것 권장
    @FunctionalInterface : 함수형 인터페이스 (컴파일 시 메서드 1개인지 체크, 안써도 OK)
    @SafeVarargs : 가변길이 인자 사용하는 메서드 선언부에 사용시 경고 무시
    @SuppressWarning : 컴파일러 경고 무시

학습 후기

이번 장은 피하고 싶던 장이었다. 대충 쓸 수 있는 정도로 알고있었는데 자세하게는 너무 어려워보여서 꼭 알아야 하는게 아니라면 자세히 알고싶지 않은... 그래도 꾹꾹 참고 공부했는데 너무 설명이 잘 되어있어 이해할 수 있었다. 제너릭/어노테이션의 사용법 뿐 아니라 어떻게, 왜 만들어졌는지까지 알려주셔서 정말... 작가님이 계속계속 글을 써주시면 좋겠다.

profile
개발 공부중!

0개의 댓글