본문 바로가기

JAVA/기본

제네릭스 <> (Generic)

제네릭스 <> (Generic)

public class C02generic {
    public static void main(String[] args) {
        //이렇게 인스턴스 생성할때 타입을 결정할 수 있음
        //타입은 참조 타입만 가능
        MyClass02<Object> o1 = new MyClass02<Object>();
        MyClass02<String> o2 = new MyClass02<String>();
        
        //이렇게 뒤에는 생략 가능
        MyClass02<Integer> o3 = new MyClass02<>();

        //기본타입은 안됨
        MyClass02<int> o4 = new MyClass02<int>();
    }
}

//generic type
//<T> 아직 어떤 타입으로 받을지 결정을 못했을 때 <T>로 우선 둔다.
//<T>는 타입 파라미터 (TypeParameter) 라고 한다.
// 타입파라미터 작성 규칙
// 대문자 한글자 사용
// T : type
// V : value
// N : Number
// K : key
// E : element
// S, U, T1, T2 : 기타 등등
//자세히 알고 싶다면 자바 api 문서 참조 https://docs.oracle.com/javase/tutorial/java/generics/types.html
class MyClass02<T> {

    //field도 마찬가지
    private T a;

}

예제)

public class C04generic {
    public static void main(String[] args) {
        
        MyClass04<String> o1 = new MyClass04<>();
        o1.setField("java");
        System.out.println(o1.getField());

        MyClass04<Integer> o2 = new MyClass04<>();
        o2.setField(99);
        System.out.println(o2.getField());
        
        
    }
}

class MyClass04<T> {
    private T field;

    public void setField(T field) {
        this.field = field;
    }

    public T getField() {
        return field;
    }
}

와일드 카드 (wildCard)

<? super class명> : super 인 경우 상위타입으로 가능

<? extends class명> : extends 인 경우 하위타입으로 가능

<?> : 어떤 타입이든 가능 / 궁극적으로 모든 클래스의 상위 클래스인 Object의 메소드를 사용하고 싶을 때 ? 사용


public class C06wildcard {
    public static void main(String[] args) {
        Dog d = new Dog();
        Animal a1 = d;
        Cat c = new Cat();
        Animal a2 = c;

        MyClass06<Dog> o1 = new MyClass06<>();
//        MyClass06<Animal> o2 = o1; //?
//        o2.set(new Animal());

        MyClass06<? extends Animal> o3 = o1;
        MyClass06<? extends Animal> o6 = new MyClass06<Animal>();
        MyClass06<? extends Animal> o7 = new MyClass06<Dog>();
        MyClass06<? extends Animal> o8 = new MyClass06<Cat>();
//        MyClass06<? extends Animal> o9 = new MyClass06<Object>(); // x
		//extends 일때는 get이 안전 
        Animal ani1 = o3.get(); // 안전
//        o3.set(new Dog());// 안전 하지 않음
//        o6.set(new Cat());
//        o7.set(new Dog());
        ani1.animalMethod(); // 안전하게 사용하기 위함

        MyClass06<? super Animal> o4 = new MyClass06<Animal>();
        MyClass06<? super Animal> o5 = new MyClass06<Object>();
//        MyClass06<? super Animal> o10 = new MyClass06<Dog>(); // x
		
        //super 일때는 set이 안전
        o4.set(new Dog());
        o5.set(new Dog());
        o4.set(new Cat());
        o4.set(new Animal());

    }
}

class Animal {
    public void animalMethod() {}
}
class Dog extends Animal {}
class Cat extends Animal {}

class MyClass06<T> {
    public void set(T param) {}
    public T get() {
        return null;
    }
}