제네릭

가언·2024년 8월 2일

제네릭?

  • 클래스 내부에서 사용할 객체를 외부에서 사용자 정의해서 쓸 수 있는 기술

왜 제네릭을 쓸까? [제네릭의 장점]

  1. 다운캐스팅을 안해줘도 됨=바로 꺼내쓰기 가능
  2. 컴파일 시점에서 캐스팅 가능 여부 알려줌
package com.example.summer.generic;

public class GenericClassDemo {
    private static Component t;
    private static Component component;

    public static void main(String[] args) {
        BoxObject boxObject=new BoxObject();
        boxObject.o=new Object();
        System.out.println(boxObject.o.toString());


        BoxGeneric<Object> boxGeneric=new BoxGeneric<>();
        boxGeneric.t=new Object();
        System.out.println(boxGeneric.t.toString());

        BoxObject boxComponent=new BoxObject();
        boxComponent.o=new Component();
        Component component =(Component) boxComponent.o; //down grading을 해야하고
        System.out.println(component.field);


        BoxGeneric<Component> boxGenericComponent=new BoxGeneric<>();
        boxGenericComponent.t=new Component();
        System.out.println(boxGenericComponent.t.field);//그냥 꺼내써도 됨

        String str1=(String) boxObject.o;
        String str2=(String) boxGeneric.t;
        //String str3=(String) boxGenericComponent.t;

    }
}

class BoxGeneric<T>{
    T t;
}
class BoxObject{
    Object o;
}
class Component{

    String field;
}

그렇다면 아래 코드가 가능할까?

1) String str1=(String) boxObject.o; : NO!
2) String str2=(String) boxGeneric.t; : NO!

-->String 타입으로 안전하게 사용하려면 타입 확인 및 적절한 캐스팅이 필요함!

제네릭 메소드

클래스와 독립적으로 제네릭을 운용(사용)할 수 있는 메소드

class GenericClass<C>{
    C c;
    //제네릭 클래스
    public C methodC(C c){ //외부에서 정해준 객체 C 다 같은 것
        return c;
    }
    //제네릭 메소드
    public <M> M methodM(M m){ //<M>: 나 제네릭 메소드라고 선언하는 것
        return m;

    }
    public <G> C multiMethod(G g, C c){ //제네릭메소드꺼+ 클래스꺼 반환타입은 클래스꺼(멀티 가능)
        return c;
    }


}

예시) 아래 T들에 대해 구별해보자

class ClassWithGenericMethod<T> {
    // 클래스명 옆의 T와 같은 타입.
    // 객체 생성 시점에 정해진 타입으로 결정, 타입을 바꾸고 싶으면 해당 타입의 객체를 새로 만들어야 함.
     T t;

     // 필드의 T과 다른 독립적인 타입, 객체 생성 때와 다른 타입 가능.(덮어쓰기 가능)
     // 이때 메소드의 T는 동적 타입으로 메소드를 호출할 때마다 모든 타입 가능!
     public <T> T genericMethod(T t1, T t2) {
         return t1;
     }
}

class BoxGeneric2<T> {
    // 클래스명 옆의 T와 같은 타입으로만 가능하다.<T> 선언X
    public void test(T t1) {
    }
}
  • 제네릭 메소드는 클래스 레벨의 타입과 독립적으로 메소드 레벨의 타입으로 덮어쓰기가 가능하다!

< T > 타입 파라미터

  • < T >
  • < S >
  • < U >
  • 아무의미 없음, 암묵적인 약속일뿐
profile
@gari_guri

0개의 댓글