본문 바로가기

프로그래밍/자바

[자바/기본] Generic 이란?

728x90
반응형
SMALL

 

이전글에 Wrapper 클래스에 이어서 Generic에 대해서 포스팅 하고자 한다.

Generic 클래스란?

  • generic의 사전적 의미는 일반적으로 라는 뜻
  • 클래스의 멤버변수 혹은 메소드의 리턴 타입이나 매개변수의 리턴타입을 지정하지 않고 일반적으로 정의 하는 클래스
    • 본인은 사용자가 원하는 클래스로 사용하고 싶을때 사용할 수 있는 "다형성" 을 만족시켜줄 수 있는 클래스라고 이해
  • 원하는 동작을 같지만 데이터 타입만이 다른 경우 Generic으로 설계함으로써 코드 생산성을 향상시킬 수 있다!
  • <> (많은 블로거들이 꺽쇠 라는 단어로 표현) 안에 타입매개변수 (type parameter)를 지정한다. [Java7 이후 Diamonds 라는 표현을 많이 쓴다고 함]

Why Generic 클래스?

  • 앞서 설명했다 시피 Generic 클래스를 통해 우리는 코드의 생산성을 향상시킬 수 있다.
  • 다양한 타입의 객체들을 다루는 메소드나 클래스에 컴파일 시의 타입체크를 해주는 기능을 지원함
  • 객체의 타입 안전성을 높이고 형변환의 번거로움이 줄어든다.
  • 만약 Generic 클래스를 사용하지 않았을 경우
    • 과일 박스 안에 하나의 과일만 (사과, 오렌지 두개 중) 들어갈 수 있다고 가정하고 코드를 작성할 때, Generic을 사용하지 않으면 사과 박스 클래스, 오렌지 박스 클래스 두개를 생성해주어야 한다. 
//Orange 클래스 생성
class Orange {

    public Orange() {
    }

    public void displayName() {
        System.out.println("Orange");
    }
} // end class Orange

//Orange 하나를 담고 있는 박스 클래스 생성
class OrangeBox{
    Orange orange;
    public OrangeBox(Orange orange){
        this.orange = orange;
    }

    public Orange pull(){
        return this.orange;
    }
}// end orangebox

//Apple 클래스 생성
class Apple {

    public Apple() {
    }

    public void displayName() {
        System.out.println("Apple");
    }
} // end class Orange


//Apple을 담고있는 AppleBox 생성
class AppleBox{
    Apple apple;
    public AppleeBox(Apple apple){
        this.apple = apple;
    }

    public Apple pull(){
        return this.apple;
    }
}// end orangebox
  • 위와 같이 Orange, Apple 클래스를 선언하고 각각의 Box를 선언해 주었다.
public class Main {
    public static void main(String[] args){

        Orange o1 = new Orange();
        OrangeBox ob1 = new OrangeBox(o1);
        ob1.pull().displayName();   //Orange

        Apple a1 = new Apple();
        AppleBox ab1 = new AppleBox(a1);
        ab1.pull().displayName();   //Apple
    }
}

 

  • 하지만 이렇게 각기 다른 박스를 만들어주어야 할까?
  • 만약 과일이 2개가 아니라 100개면 박스도 100개....클래스 200개...?
  • 위와 같은 코드의 내용을 generic을 사용해서 만들어보도록 하겠다.

class FruitBox<T> {
    T fruit;  // T 타입 필드
    public FruitBox(){}
    public FruitBox(T fruit) {this.fruit = fruit;} // T 타입 매개변수

    public T pull() { return fruit; } // 리턴타입 T
}
  • 위 FruitBox라는 Generic 클래스 선언!

 

public class Main {
    public static void main(String[] args){

        FruitBox<Orange> fb1 = new FruitBox<>(o1);
        fb1.pull().displayName();   //Orange

        FruitBox<Apple> fb2 = new FruitBox<>(a1);
        fb2.pull().displayName();   //Apple
    }
}
  • 해당 클래스를 이용하여 각각의 과일들 담을 수 있음

 

이처럼 Generic 클래스를 활용하면 코드의 생산성이 향상된다는 장점 이해 완료


More About Generic 클래스

  • 제너릭 클래스에서 사용 되는 타입은 기본자료형은 사용 될 수 없다!
    • 오직 Object 만!
  • 클래스의 Static 필드에서는 Generic을 사용할 수 없다! ****
  • 관례적으로 많이 사용하는 파라미터 명
    • <T> Type
    • <E> Element
    • <K> Key
    • <N> Number
    • <V> Value
    • <R> Result
  • 예시

출처 :&nbsp;https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html

  • Generic 을 사용하는 HashMap 의 공식문서를 보면 K (Key값) 그리고 V (Value 값) 이 들어가는 것을 볼 수 있다.

Generic 메소드

  • 앞서 설명했듯이 Generic은 메소드 에도 사용이 가능하다.
  • 예시
public static <T> T prac(T param){
    return param;
}
  • 위 의 예시 처럼 Generic 메소드는 Static이어도 사용 가능 하다.
  • 메소드 선언부에 Generic으로 리턴 타입, 파라미터 타입이 정해지는 메소드 이다.
  • <T> : 선언 부분,  선언 부분은 반드시 리턴타입 앞에 있어야 한다.

 

그래서 예시를 하나 들어서 만들어 보았다.

  • Generic 메소드를 통해 들어온 객체의 class를 print 하고 종료하는 함수를 만들고 재생 해보았다.
public class Main {
    public static void main(String[] args){
        Integer i1 = 1;
        Double d1 = 1.1;
        String s1 = "1";

        generictest(i1);	//class java.lang.Integer
        generictest(d1);	//class java.lang.Double
        generictest(s1);	//class java.lang.String
    }

    public static <T> void generictest(T object){
        System.out.println(object.getClass());
    }
}

 

  • Generic 타입을 통해 각자의 클래스를 잘 출력하는 것을 확인 할 수 있다. 

 

728x90
반응형
LIST