본문 바로가기
java

제네릭 클래스 Generics, 제너릭 클래스 메서드, <T>

by socialcomputer 2021. 9. 13.
'제너릭 generic'을 잘 알고 썼다고 생각했지만, 모르겠는 것들이 점차 생기면서 내가 잘 알고 있지 못하다는 생각이 들어 차근차근 알아보려고 한다. 

  • 먼저 제네릭 클래스의 코드를 보자. 
class FruitBox{
	Object item;
    public void store(Object item){
    	this.item = item;
    }
    public Object pullOut(){
    return item;
    }
}

class FruitBox<T>{ //제네릭 클래스를 사용하려는 형태. 타입 T에 <>꼭 써워야 한다.
	T item;
    public void store(T item){
    	this.item = item;
    }
    public T pullOut(){
    return item;
    }
}

<>는 제네릭 클래스를 사용하려는 형태이고, T는 임의로 정의한 이름이다. M, S, V등 도 있다.

참고로 제네릭은 기본자료형이 불가하다. 그런데 실제로 기본자료형인 데이터를 넣어보면 오류가 나지 않는다. 그 이유는 자동으로 wrapper클래스로 boxing unboxing 되기 때문이다. 

제네릭 클래스를 사용했을 때 -> 클래스 선언할 때 타입 파라미터 사용 후, 컴파일 시 타입 파라미터가 구체적인 클래스로 변형된다. 

 

  • 제네릭 타입은 두개 이상의 타입 파라미터 사용도 가능하다.
public class Product<T, M>{
	private T kind;
    private M model;
    
    public T getKind(){
    	return this.kind;
    }
    public M getModel(){
    	return this.model;
    }
    
    public void setKind(T kind){
    	this.kind = kind;
    }
    pulic void setModel(M model){
    	this.model = model;
    }
]

Product<Tv, String> product = new Product<>();

제너릭 클래스 예제

class DBOx<L, R>{
    private L left;
    private R = right;

    public void set(L o, R r){
        this.left = o;
        this.right = r;
    }

    @Override
    public String toString(){
        return left +"&"+ right;
    }
}

public static void main(String[] args){
    DBox<String, Integer> box = new DBox<String, Integer>();
    box.set("Apple", 25);
    System.out.print(box);//toString매소드 호출됨
}
  • 제네릭은 클래스 전체에서 사용할 수도 있지만 메서드에서도 사용할 수 있다.
매개변수 타입과 리턴 타입으로 타입T 파라미터를 갖는 메서드 
public <타입파라미터, ...> 리턴 타입 메서드명(매개변수,...)  { ........ }
public <T, V> Box<T> boxing(T t, V v) { ............ }

이런 제네릭 메소드를 호출하는 두 가지 방법이 있다.

//1
리턴타입 변수 = <구체적 타입> 메소드명(매개값);
Box<Integer> box = <Integer> boxing(100);
//2
리턴타입 변수 = 메소드명(매개값);
Box<Integer> box = boxing(100);

1번은 명시적으로 구체적 타입을 지정했고 2번은 매개값을 보고 구체적 타입을 추정한다. ->int형인 100을 보고 Integer로 추정한다.

 

이처럼 제너릭 메소드는 메소드 뒤에 있는 매개값을 보고 타입을 정하는데,  제너릭 클래스는 인스턴스 앞에 있는 데이터 형을 보고 결정한다. 많이 보던  LinkedList<Integer> list = new LinkedList<>() 에서 =뒤쪽에선 타입을 지정하지 않아도 되는 것을 알 수 있다. 

 

제너릭 메소드 예제 ( 2개 이상의 타입을 가지는 예제도 있음)

class BoxFactory{
    public static <T> Box<T> makeBox(T o){
        Box<T> = new Box<T>();
        box.set(0);
        return box;
    }
}

Box<String> sBox = BoxFactory.<String>makeBox("toys");
Box<Double> dBox = BoxFactory.<Double>makeBox(3.14);
//혹은 뒷부분 타입 생략
Box<String> sBox = BoxFactory.makeBox("toys");
Box<Double> dBox = BoxFactory.makeBox(3.14);


//두개 이상의 타입을 가지는 매소드
class InstanceTypeShower2{
    public <T, U> void showInstType(T inst1, U inst2){
        System.out.println(inst1);
        System.out.println(inst2);
    }
}

public static void main(String[] args){
    AAA aaa = new AAA();
    BBB bbb = new BBB();

    InstanceTypeShower2 shower = new InstanceTypeShower2();
    shower.<AAA, BBB>showInstType(aaa, bbb);
    //메소드 호출시는 아래처럼 자료형의 정보를 생략 가능함
    shower.showInstType(aaa, bbb);
}

 

  • 키워드 extends

extend를 이용하여 매개변수의 자료형을 제한할 수 있다. 

class Box<T extends Number>{
    private T ob;
    public void set(T o){
        ob = o; 
    }
    public T get(){
        return ob;
    }
}

public static void main(String[] args){
    Box<Integer> iBox = new Box<>();
    iBox.set(30);
    Box<Double> dBox = new Box<>();
    dBox.set(99.9);
}

Box클래스로 인스턴스 생성시 인자 타입으론 Number클래스 자체나 Number클래스를 상속하는 클래스만이 올 수 있다.

-> Integer 와 Double이 Number를 상속하기 때문에 가능하다. = Number로 제한되어 있으니 Integer와 Double...만이 올 수 있다.

 

자료형 제한을 마지막으로 제네릭을 마무리한다. 
명료하지 못했던 것이 선명해진 것 같다. 다시한번 상기시키며 공부하는 것이 좋다고 느껴진다. 
한 블로그를 참고하며 정리했는데 링크는 아래다. 요약 같을 수 있지만,, 나의 말들로 정리를 하니 더욱 이해가 되는 것 같다. 

참고 https://blog.naver.com/hke3255/222307555750

 

자바 제네릭 클래스 (Generics,제네릭 메소드,<>,,타입 인자,JAVA,java,안드로이드 자바,쉬운 예제,

JAVA 제네릭 제네릭 클래스의 이해와 설계 제네릭을 구성하는 다양한 문법적 요소 AppleBox와 Orang...

blog.naver.com

 

'java' 카테고리의 다른 글

java 중복 없애주는 set, 객체는?  (0) 2022.05.11
java optional stream()  (0) 2022.02.03
[String] replace, replaceAll과 정규식  (0) 2021.11.17
[java] 이중 콜론 연산자 ::  (0) 2021.09.12

댓글