본문 바로가기
개발/자바

자바 ) Generic (제네릭) 이해하기

by kakk789 2023. 2. 6.

Generic(제네릭) 이란?

  • 데이터 형식에 의존하지 않고 여러 데이터 타입을 사용할 수 있도록 함.

장점

  • 중복 코드를 제거하여 재사용성을 높임.
    제네릭 타입으로 선언된 클래스에서 타입 별로 생성자 및 getter, setter를 만들 필요가 없음 (재사용성 증가)

1. 클래스에서 사용

MyGeneric 클래스 생성

 class MyGeneric <T>{
    T val;

    public MyGeneric(T val) {
        this.val = val;
    }

     public T getVal() {
         return val;
     }

     public void setVal(T val) {
         this.val = val;
     }
 }
MyGeneric string11 = new MyGeneric("11"); //String
MyGeneric int11 = new MyGeneric(11); // Integer

System.out.println(string11.getVal().getClass()); // String
System.out.println(int11.getVal().getClass());  // Integer

2. 메소드에서 사용

  • 리턴 타입, 파라미터 타입에 같은 타입을 넣어야 함
  • 그냥 클래스 선언 시 <T> 를 작성하면 되는데 왜 굳이 메서드에 사용하면 해당 메소드만 적용시키시 위해서 사용하는 것으로보임.
class Test {
    public <T> void setGen(T a){
        System.out.println("해당 파라미터의 클래스 : " + a);
    }
}
Test test = new Test();
test.setGen(1);		// 1	-> Integer
test.setGen(1.0);	// 1.0  -> Double
test.setGen("11");	// 11   -> String

제네릭 제약의 필요성

  • 제약 없이 제네릭을 사용하면 너무 러프해져서 생각치 못한 타입이 삽입되어 에러가 발생할 수 있다.
  • 따라서, 제약을 걸어 오류를 줄여야 한다.
  • 기준은 클래스의 상하관계로서 상한선(extends), 하한선(super)을 걸어주면 된다.

1. extends T

  • 상한 경계T와 T의 자손 타입에 대해서만 지정 가능하다.
  • 예를들어 클래스 선언 시 <T extends Number> 로 지정하게 되면 Number 타입과 Number의 하위 자식 타입만 사용 가능하다.
<? extends T> : 메소드의 매개변수와 리턴타입에 사용
<K extend T>  : 클래스 선언시, 그리고 메소드의 리턴 타입 파라미터에 사용 (매개변수 X)

 

1. <K extend T>

//class 타입 형태로 사용
public Class classNumber <T extends Number>{ ... }

// 메소드의 타입 파라미터 형태로 사용
public <T extends Number) int methodNumber(T t){ ... }

2. <? extends T> 

// 메소드의 매겨변수에 사용
public void methodNumber(List<? extends Number> list){ ... }

// 메소드의 리턴타입에 사용
public List<? extends Number> methodNumber() { ... }

예시 코드 1) <K extend T> --> class에서 사용

 class MyGeneric <T extends Number>{
    E val;

    public MyGeneric(T val) {
        this.val = val;
    }

     public T getVal() {
         return val;
     }

     public void setVal(T val) {
         this.val = val;
     }
 }

예시 코드 2)

MyGeneric string11 = new MyGeneric("11"); // -> 에러 발생 (String이므로 에러)
MyGeneric int11 = new MyGeneric(11); // 정상 작동

에러 발생 내역

2. super T

  • 하한 경계T와 T의 부모타입에 대해서만 지정 가능하다.
  • super의 경우 <? super T> 형태처럼 와일드카드를 사용하여 사용해야만한다.
  • 메소드의 매개변수와 리턴타입에 사용
<? super T> 

1. <? super T> 

public static void methodSuper(List<? super Number> list){ ... }

참고자료

https://yarisong.tistory.com/48
https://yarisong.tistory.com/47
https://pathas.tistory.com/160
반응형

댓글