Java의 정석 - 제네릭

원태연·2022년 5월 30일
0

Java의 정석

목록 보기
13/19
post-thumbnail

제네릭

제네릭(Generics)이란?

다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스를 컴파일 할 때, 타입을 체크해주는 기능

=> 객체들의 타입 안정성과 형변환의 번거로움이 줄어드는 기대를 할 수 있다.

제네릭 클래스

class Box<T>{
    T item;
    void setItem(T item){
        this.item = item;
    }
    T getItem(){
        return item;
    }
}

T는 타입변수이다. T라는 변수에 여러 타입들이 들어갈 수 있는것이다. TInteger,String,Objcet등 여러 타입이 된다.

Box<String> stringBox = new Box<String>;
// T라는 타입변수에 String타입을 지정하였다

Box<Integer> integerBox = new Box<Integer>;
// T라는 타입변수에 Integer타입을 지정하였다

제네릭 제한

class Box<T>{
  //static T item; ERROR   --1
  T[] itemArr;
  T[] toArray(){
//    T[] tmpArr = new T[itemArr.length]; ERROR --2
  }
}

당연한 얘기겠지만, static멤버는 제네릭 클래스에 존재할 수 없다(--1). 타입변수가 존재하기 때문에 클래스변수가 존재하면 다른 타입으로 저장될 수 있기 때문이다.

--2를 보면 제네렉배열을 생성하는 단계에서 에러가 난다. new라는 연산자는 T(타입)에 대해 정확히 알고 있어야 하기 때문이다. 위 예시처럼 배열 뿐만아니라, T객체 생성도 불가하다. 굳이 사용하고자 한다면, newInstance()라는 API를 사용할 수 있다.

class Box<T extends Fruit>{
  ArrayList<T> list = new ArrayList<>(); //--1
}

extends를 사용하면, T라는 타입변수는 Fruit 타입과 그 자손들만 대입이 가능하도록 제한을 둘 수 있다.

--1list에는 Fruit와 자손관계인 Apple,Grape와 같은 타입들만 저장될 수 있도록 제한이 되었다.

와일드 카드

제네릭 타입간의 다형성을 부여할 수 있다.

<? extends T> : 와일드 카드의 상한 제한. T와 그 자손들만 가능
  
<? super T>   : 와일드 카드의 하한 제한. T와 그 조상들만 가능
  
<?>           : 모든 타입이 가능 (<? extends Object>와 동일) 

예를 들어,

class Parent{}
class Child extends Parent{}
class GrandChild extends Parent{}
public class playGround{
    public static void play(){
//        ArrayList<Parent> parentList = new ArrayList<Child>;
        ArrayList<? extends Parent> parentList = new ArrayList<Parent>;
        parentList = new ArrayList<GrandChild>;
    }
}

실용적인 예시는 아니지만, 와일드카드를 통해 제네릭 타입간의 다형성을 사용할 수 있다.

profile
앞으로 넘어지기

0개의 댓글