201224 제네릭

2020-12-24

제네릭

  • 어떤 값이 하나의 참조 자료형이 아닌 여러 참조 자료형을 사용할 수 있도록 프로그래밍함
    • 여러 참조 자료형이 쓰일 수 있는 곳에 특정 자료형을 지정하지 않고, 클래스나 메서드를 정의한 후 사용하는 시점에 어떤 자료형을 사용할지 지정한다
  • 제네릭 프로그램: 참조 자료형이 변환될 때 이에 대한 검증을 컴파일러가 하므로 안정적이다

제네릭 클래스의 정의

public class GenericPrinter<T>{
    private T material;
    
    public void setMaterial(T material){
        this.material=material;
    }
    
    public T getMaterial(){
        return material;
    }
}
  • T : 자료형 매개변수(Type parameter)

  • 다이아몬드 연산자 <>

    • ArrayList<String> list = new ArrayList<>();
    • 자바 7부터는 제네릭 자료형의 클래스를 생성할 때 생성자에 사용하는 자료형을 명시하지 않을 수 있다
    • 선언된 자료형을 보고 생략된 부분을 컴파일러가 유추할 수 있기 때문에 생성 부분에서는 생략 가능하다
    • 자바 10 이후로는 지역 변수에 한해 자료형을 추론할 수 있다
      • var list = new ArrayList<String>();

자료형 매개변수 T와 static

  • static 변수의 자료형이나 static 메서드 내부 변수의 자료형으로 T를 사용할 수 없다
    • static 변수/메서드: 인스턴스를 생성하지 않아도 클래스 이름으로 호출 가능
    • T의 자료형이 정해지는 순간: 제네릭 클래스 인스턴스가 생성되는 순간
  • 자료형 매개변수 T 외 다른 문자도 사용 가능하다
    • E(element), K(key), V(value)….
용어 설명
ArrayList<String> 제네릭 자료형(Generic type), 매개변수화된 자료형(parameterized type)
String 대입된 자료형
  • 제네릭 구현시 형변환이 필요하지 않은 이유?
    • 제네릭 클래스 사용시 컴파일러는 일단 대입된 자료형이 잘 쓰였는지 확인
    • class파일 생성시 T를 사용한 곳에 지정된 자료형에 따라 컴파일하므로 형변환을 하지 않아도 됨

  • 제네릭 클래스에서는 T 자료형에서 사용할 자료형에 제한을 둘 수 있다
    • 제네릭 클래스를 사용할 때 상위클래스에서 선언한 메서드를 사용할 수 있다

제네릭 클래스와 제네릭 메서드

public calss Point<T,V>{
    // 제네릭 클래스에서 자료형 매개변수를 여러 개 사용할 수 있다
    T x;
    V y;
    
    point(T x, V y){
        this.x=x;
        this.y=y;
    }
    
    public T getX(){
        return x;
    }
    
    public V getY(){
        return y;
    }
}
public class GenericMethod{
    // GenericMethod 클래스는 제네릭 클래스가 아니다!
    // 제네릭 클래스가 아니더라도 제네릭 메서드를 구현할 수 있다.
    public static <T,V> double makeRectangle(Point<T,V> p1, Point<T,V> p2){
        double left = ((Number)p1.getX()).doubleValue();
        double right = ((Number)p2.getX()).doubleValue();
        double top = ((Number)p1.getY()).doubleValue();
        double bottom = ((Number)p2.getY()).doubleValue();
        
        double width = right - left;
        double height = bottom - top;
        
        return width * height;
    }
    
    public static void main(String[] args){
        Point<Integer,Double> p1 = new Point<Integer, Double>(0, 0.0);
        Point<Integer,Double> p2 = new Point<Integer, Double>(10, 10.0);
        
        double rect = GenericMethod.<Integer,Double>makeRectangle(p1,p2);
    }
}

출처

Do it! 자바 프로그래밍