June

<자바기초> generic에서 타입 제한하기

제네릭 제한과 하면 안되는 부분에 대해 간략히 알아보겠습니다.

package generic;

abstract class Info
{
    public abstract int getLevel();
}

class levelInfo extends Info
{
    public int rank;
    public levelInfo(int rank)
    {
        this.rank = rank;
    }

    public int getLevel()
    {
        return this.rank;
    }
}

class Paper<T extends Info, S>  // Info가 interface여도 상관 없이 extends로 받아옴.
{                               // super 명령어는 extends 와 반대로, 해당 클래스만 제외한다는 뜻.
    public T info1;
    public S info2;
    public Paper(T info1, S info2)
    {
        this.info1 = info1;
        this.info2 = info2;
    }
    public <U> void printInfo(U info)
    {
        System.out.println(info);
    }
}

public class LimitsGeneric
{
    public static void main(String[] args)
    {
        levelInfo li = new levelInfo2(3);
        Paper<levelInfo, Integer> p2 = new Paper2<levelInfo, Integer> (li, 3);
        Paper<String, Integer> p3 = new Paper<String, Integer> ("String", 3); // error! Info를 상속받은 클래스만 사용 가능.
    }
}

원래 Wrapper 클래스로 써야 하지만, Paper<String, Integer> p3 = new Paper<String, Integer> ("String", 3); 에서 3 같은 경우는 auto-boxing으로 자동으로 Integer 형태로 바뀝니다.


위 Paper 클래스에서 extends가 없으면 당연하게 getLevel() 메서드는 사용할 수 없습니다.
평소에 class Paper<T>라고 쓰는 형태는 사실 아래와 같은 형태를 축소해 놓은 것이기 때문입니다. 그래서 info는 Object의 기본 메서드만 사용할 수 있습니다.

class Paper<T extends Object>
{
    public Person(T info)
    {
        info.getLevel();    // 사용 불가 Object형식만 가능. getLevel은 Info를 상속받은 애들만 구현했으니까.
     }
 }

제가 보던 책에도 없던 부분이지만 중요하게 쓰일 수 있을 법 한 부분이었습니다.