제네릭(Generic) 프로그래밍

Kim taegwan·2026년 3월 31일

제네릭 프로그래밍의 주요 이점

  1. 타입 안정성: 컴파일 시 타입을 검사하여 런타임 에러를 줄일 수 있습니다.
  2. 코드 재사용성: 다양한 타입을 처리할 수 있는 일반화된 코드를 작성할 수 있습니다.
  3. 유지보수성: 타입 캐스팅을 줄여 가독성과 유지보수성을 향상시킵니다.
package generic.ch02;

/**
 * 제네릭 프로그래밍
 * 문법 : 클래스, 데이터타입, 메서드 등에서 <T> 대체 문자열을 선언할 수 있다.
 */
public class GenericPrinter<T> {

   // T(type) 라는 대체 문자 사용 가능 E, K, V (사실 아무 의미없는 문자열일 뿐이다)
   // 자료형 매개변수 (type parameter)
   T material;

   public T getMaterial() {
       return material;
   }

   public void setMaterial(T material) {
       this.material = material;
   }

}
package generic.ch02;

import generic.ch01.Plastic;
import generic.ch01.Powder;

import java.util.ArrayList;

public class GenericMain {

    public static void main(String[] args) {
        // 제네릭 프로그래밍을 활용하면 타입에 안정성을 줘서 컴파일 시 (코드 작성시)
        // 명확하게 타입을 지정할 수 있다.
        Plastic plastic1 = new Plastic();
        Powder powder1 = new Powder();
        Water water1 = new Water();

        ArrayList<Integer> integers;
        // 사용하는 시점에는 무엇을 넣을지 미리 지정해 주어야 한다.
        GenericPrinter<Plastic> genericPrinter = new GenericPrinter();
        // 컴파일 시점에 플라스틱을 넣기로 했는데 다른 타입이 들어가면 컴파일 오류가 발생한다.
        // genericPrinter.setMaterial(powder1);
        genericPrinter.setMaterial(plastic1);
        Plastic tempPlastic = genericPrinter.getMaterial();

        // 컴파일 시점에 역시 타입을 확인 할 수 있도 추가로 다운캐스팅 작업도 필요가 없다.
        // Powder tempPlastic = genericPrinter.getMaterial();
        System.out.println("-----------------------------------------");

        // 자료형 매개변수는 무엇이든 다 담을 수 있지만 이 또한 단점들이 발생 할 수 있다.
        GenericPrinter<Water> waterGenericPrinter = new GenericPrinter<>();
        waterGenericPrinter.setMaterial(water1);
        System.out.println(waterGenericPrinter.getMaterial());

    }

}
package generic.ch02;

public class Water {

    @Override
    public String toString() {
        return "재료는 물 입니다";
    }
}

<T extends 클래스> 사용하기

상위 클래스의 필요성 - (물이라는 재료를 넣어서 마구 활용하는 것을 막을 수 있다.)

● T 자료형의 범위를 제한 할 수 있음

● 상위 클래스에서 선언하거나 정의하는 메서드를 활용할 수 있음

package generic.ch03;

public abstract class Material {

    public abstract void showInfo();
}
package generic.ch03;

public class Plastic extends Material {

    @Override
    public void showInfo() {
        System.out.println("재료는 플라스틱 입니다");
    }
}
package generic.ch03;

public class Powder extends Material {

    @Override
    public void showInfo() {
        System.out.println("재료는 파우더 입니다");
    }
}
package generic.ch03;

/**
 *
 * <T extends 클래스> 를 사용하면 현재 코드에서 Material 을 상속받은 자식 클래스만
 * 대체 문자열에 들어 올 수 있다.
 */
public class GenericExtendsPrinter<T extends Material> {

    T material;

    public T getMaterial() {
        return material;
    }

    public void setMaterial(T material) {
        this.material = material;
    }

}
package generic.ch03;

import generic.ch02.Water;

public class MainTest {

    public static void main(String[] args) {

        Water water1 = new Water();
        Plastic plastic1 = new Plastic();
        Powder powder1 = new Powder();

        // GenericExtendsPrinter <-- 제네릭 클래스로 설계 되어 있어서 <> 를 사용할 수 있다.

        // GenericExtendsPrinter<Water> printer = new GenericExtendsPrinter();
        // 오류 발생 - Water 타입은 Material 의 자식이 아니기 때문에 사용할 없음
        GenericExtendsPrinter<Plastic> printer = new GenericExtendsPrinter<>();
        printer.setMaterial(plastic1);

        System.out.println(printer.getMaterial());
        printer.getMaterial().showInfo();

    }
}

0개의 댓글