
제네릭 자료형 정의
- 클래스에서 사용하는 변수의 자료형이 여러개 일수 있고, 그 기능(메서드)은 동일한 경우 클래스의 자료형을 특정하지 않고 추후 해당 클래스를 사용할 때 지정 할 수 있도록 선언
- 실제 사용되는 자료형의 변환은 컴파일러에 의해 검증되므로 안정적인 프로그래밍 방식
- 컬렉션 프레임워크에서 많이 사용되고 있음
제네릭 타입을 사용하지 않는 경우의 예
재료가 Powder인 경우
public class ThreeDPrinter1{
private Powder material;
public void setMaterial(Powder material) {
this.material = material;
}
public Powder getMaterial() {
return material;
}
}
재료가 Plastic인 경우
public class ThreeDPrinter2{
private Plastic material;
public void setMaterial(Plastic material) {
this.material = material;
}
public Plastic getMaterial() {
return material;
}
}
- 여러 타입을 대체하기 위해 Object를 사용할 수 있음
public class ThreeDPrinter{
private Object material;
public void setMaterial(Object material) {
this.material = material;
}
public Object getMaterial() {
return material;
}
}
- Object를 사용하는 경우는 형 변환을 하여야 함
ThreeDPrinter printer = new ThreeDPrinter();
Powder powder = new Powder();
printer.setMaterial(powder);
Powder p = (Powder)printer.getMaterial();
제네릭 틀래스 정의
GenericPrinter.java
public class GenericPrinter<T> {
private T material;
public void setMaterial(T material) {
this.material = material;
}
public T getMaterial() {
return material;
}
public String toString(){
return material.toString();
}
}
- 자료형 매개변수 T(type parameter) : 이 클래스를 사용하는 시점에 실제 사용할 자료형을 지정, static 변수는 사용할 수 없음
- GenericPrinter : 제네릭 자료형
- E : element, K: key, V : value 등 여러 알파벳을 의미에 따라 사용 가능
GenericPrinterTest.java
public class GeneriPrinterTest {
public static void main(String[] args) {
GenericPrinter<Powder> powderPrinter = new GenericPrinter<>();
powderPrinter.setMaterial(powder);
Powder p = powderPrinter.getMaterial();
System.out.println(p);
System.out.println(powderPrinter.toString());
GenericPrinter<Plastic> plasticPrinter = new GenericPrinter<Plastic>();
plasticPrinter.setMaterial(new Plastic());
Plastic pl = plasticPrinter.getMaterial();
System.out.println(pl);
System.out.println(plasticPrinter);
}
}
결과
재료는 Powder
GenericPrinter [material=재료는 Powder]
재료는 Plastic
GenericPrinter [material=재료는 Plastic]
<T extends 클래스> 사용
상위 클래스의 필요성
- T 자료형의 범위를 제한 할 수 있음
- 상위 클래스에서 선언하거나 정의하는 메서드를 활용할 수 있음
- 상속을 받지 않는 경우 T는 Object로 변환되어 Object 클래스가 기본으로 제공하는 메서드만 사용가능
써야하는 재료에 대해 한정을 지어주고, 공통으로 쓸 수 있는 메서드들을 상위클래스에서 지정할 수있습니다.
T extends 를 사용한 프로그래밍

- GenericPrinter 에 material 변수의 자료형을 상속받아 구현
- T에 무작위 클래스가 들어갈 수 없게 Material 클래스를 상속받은 클래스로 한정
T extends Material을 통해 제네릭에 들어가선 안될 타입이 들어가는 것을 막아줍니다.
GenericPrinter.java
public class GenericPrinter<T extends Material> {
private T material;
public void setMaterial(T material) {
this.material = material;
}
public T getMaterial() {
return material;
}
public String toString(){
return material.toString();
}
public void printing() {
material.doPrinting();
}
}
GenericPrinterTest.java
public class GenericPrinterTest {
public static void main(String[] args) {
GenericPrinter<Powder> powderPrinter = new GenericPrinter<Powder>();
powderPrinter.setMaterial(new Powder());
Powder powder = powderPrinter.getMaterial(); // 형변환 하지 않음
System.out.println(powderPrinter);
GenericPrinter<Plastic> plasticPrinter = new GenericPrinter<Plastic>();
plasticPrinter.setMaterial(new Plastic());
Plastic plastic = plasticPrinter.getMaterial(); // 형변환 하지 않음
System.out.println(plasticPrinter);
//GenericPrinter<Water> printer = new GenericPrinter<Water>(); //상속받지않은 material이므로 불가능
}
}
제네릭 메서드 활용
제네릭 메서드란?
- 자료형 매개변수를 메서드의 매개변수나 반환 값으로 가지는 메서드는 자료형 매개 변수가 하나 이상인 경우도 있음
- 제네릭 클래스가 아니어도 내부에 제네릭 메서드는 구현하여 사용 할 수 있음
- public <자료형 매개 변수> 반환형 메서드 이름(자료형 매개변수.....) { }
제네릭 메서드의 활용 예
- 두 점(top, bottom)을 기준으로 사각형을 만들 때 사각형의 너비를 구하는 메서드를 만들어 보자
- 두 점은 정수인 경우도 있고, 실수인 경우도 있으므로 제네릭 타입을 사용하여 구현한다.
Point.java
public class Point<T, V> {
T x;
V y;
Point(T x, V y){
this.x = x;
this.y = y;
}
public T getX() {
return x;
}
public V getY() {
return y;
}
}
GenericMethod.java
static <T,V> double 에서 <T,V>는 자료형 매개변수이고 double이 반환형입니다.
public class GenericMethod {
public static <T, V> double makeRectangle(Point<T, V> p1, Point<T, V> p2) {
double left = ((Number)p1.getX()).doubleValue();
double right =((Number)p2.getX()).doubleValue();
double top = ((Number)p1.getY()).doubleValue();
double bottom = ((Number)p2.getY()).doubleValue();
double width = right - left;
double height = bottom - top;
return width * height;
}
public static void main(String[] args) {
Point<Integer, Double> p1 = new Point<Integer, Double>(0, 0.0);
Point<Integer, Double> p2 = new Point<>(10, 10.0);
double rect = GenericMethod.<Integer, Double>makeRectangle(p1, p2);
System.out.println("두 점으로 만들어진 사각형의 넓이는 " + rect + "입니다.");
}
}
결과
두 점으로 만들어진 사각형의 넓이는 100.0입니다.'Java' 카테고리의 다른 글
| [Java] 예외 처리 (0) | 2022.10.02 |
|---|---|
| [Java] 자바의 유용한 클래스 (0) | 2022.10.01 |
| [Java] 자료구조 (0) | 2022.10.01 |
| [Java] 컬렉션 프레임워크 (0) | 2022.10.01 |
| [Java] 다형성 / 다운 캐스팅 (1) | 2022.09.23 |