728x90
반응형
제네릭
- 결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때(인스턴스 생성 시) 파라미터를 구체적인 타입으로 대체시키는 기능.
- <T>는 T가 타입 파라미터임을 뜻하는 기호.
제네릭 타입
- 결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스.
- 선언부에 '< >'부호가 붙고 그 사이에 타입 파라미터들이 위치.
- 타입 파라미터는 일반적으로 대문자 알파벳 한 글자로 표현.
- 외부에서 제네릭 타입을 사용하려면 타입 파라미터에 구체적인 타입을 지정. 지정하지 않으면 Object 타입이 암묵적으로 사용.
제네릭 메서드
- 타입 파라미터를 가지고 있는 메서드. 타입 파라미터가 메서드 선언부에 정의.
- 리턴 타입 앞에 < > 기호 추가하고 타입 파라미터 정의 후 리턴 타입과 매개변수 타입에서 사용.
- 타입 파라미터 T는 매개값의 타입에 따라 컴파일 과정에서 구체적인 타입으로 대체.
제한된 타입 파라미터
- 모든 타입으로 대체할 수 없고, 특정 타입과 자식 또는 구현 관계이 있는 타입만 대체할 수 있는 타입 파라미터.
- 상위 타입은 클래스 뿐만 아니라 인터페이스도 가능.
와일드카드 타입 파라미터
- 제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 범위에 있는 모든 타입으로 대체할 수 있는 타입 파라미터(?로 표시)
클래스에서의 예제
package generic.classEx;
public class GenericEx01 {
public static void main(String[] args) {
Box<String> box = new Box<String>();
box.content = "러브 레터";
String content = box.content;
System.out.println(content);
Box<Integer> box1 = new Box<Integer>();
box1.content = 100;
int content1 = box1.content;
System.out.println(content1);
Box<Doll> box2 = new Box<Doll>();
box2.content = new Doll();
Doll content2 = box2.content;
System.out.println(content2);
Product<SmartPhone, String> p1 = new Product<SmartPhone, String>();
p1.setKind(new SmartPhone());
p1.setModel("Apple 15 pro max");
SmartPhone applePhone = p1.getKind();
String applePhoneModel = p1.getModel();
System.out.println(applePhone + " : " + applePhoneModel);
Product<Car, String> c1 = new Product<Car, String>();
c1.setKind(new Car());
c1.setModel("Ferrari SF90");
Car ferrari = c1.getKind();
String ferrariModel = c1.getModel();
System.out.println(ferrari + " : " + ferrariModel);
}
}
package generic.classEx;
public class Box <Z>{
public Z content; // 해당 Box 안에는 다양한 내용물들이 저장될 수 있으므로 특정 클래스 타입으로 선어할 수 없다.
// 그러므로, 모든 타입 즉 모든 클래스의 최상위 부모 클래스로 자동 프로모션 되므로 content 필드에는 어떤 객체도 대입될 수 있다.
}//T는 파라미터 타입(기호)라고 한다.
package generic.classEx;
public class Doll {
public String name = "미미";
public String company = "영실업";
}
package generic.classEx;
import lombok.Getter;
import lombok.Setter;
//@Getter
//@Setter
public class Product <K, M> { // 제네릭 타입의 클래스
private K kind; // 타입 파라미터 K를 kind 필드의 타입으로 사용하겠다.
private M model; // 타입 파라미터 M를 model 필드의 타입으로 사용하겠다.
public K getKind() {
return kind;
}
public void setKind(K kind) {
this.kind = kind;
}
public M getModel() {
return model;
}
public void setModel(M model) {
this.model = model;
}
}
package generic.classEx;
public class Car {
}
package generic.classEx;
public class SmartPhone {
}
인터페이스에서의 예제
package generic.interfaceEx;
public class RentEx {
public static void main(String[] args) {
Codi codi = new Codi();
AirConditioner airConditioner = codi.rent();
airConditioner.powerOn();
}
}
package generic.interfaceEx;
public interface Rentable<P> {//다양한 대상을 렌트하기 위한 rent() 메서드의 타입을 타입 파라미터로 지정
public P rent();
}
package generic.interfaceEx;
public class AirConditioner {
public void powerOn(){
System.out.println("공기 청정기 전원을 켭니다.");
}
}
package generic.interfaceEx;
public class Codi implements Rentable<AirConditioner>{
@Override
public AirConditioner rent() {
return new AirConditioner();
}
}
추가 예제
package generic.genericMethodEx;
import generic.classEx.Doll;
public class GenericBoxEx {
public static void main(String[] args) {
Box<Integer> box1 = boxing(100);
int value1 = box1.getType();
System.out.println(value1);
//"포켓몬 포토카드"를 박싱하여 포장해주세요.
Box<String> box2 = boxing("포켓몬 포토카드");
//상자에서 포켓몬 포토카드를 꺼내주세요.
String value2 = box2.getType();
System.out.println(value2);
//상자에서 미미 인형을 꺼내서 이름과 제조업체를 확인해 주세요.
Box<Doll> box3 = boxing(new Doll());
System.out.println(box3.getType().name);
System.out.println(box3.getType().company);
}
public static <T> Box<T> boxing(T t){
Box<T> box = new Box<T>();
box.setType(t);
return box;
}
}
package generic.genericMethodEx;
public class Box <T>{
private T type;
public T getType() { //제네릭 메서드 get
return type;
}
public void setType(T type) { // 제네릭 메서드 set
this.type = type;
}
}
제네릭을 써야 하는 이유
- 자바에서 타입의 안정성을 고려 혹은 향상시켜줌.
- 코드의 재사용성을 증가시킬 수 있음 -> 제네릭을 사용함으로써 개발자는 컴파일 시점에 타입 체크를 할 수 있기 때문.
- 만약 제네릭을 사용하지 않으면, 컬렉션(자바에서 제공하는 자료구조)은 다양한 객체 타입의 객체를 저장할 수 있는데 이렇게 되면 타입 안정성을 보장해주지 못하며, 객체를 검색하거나 사용할 때마다 타입 비교와 타입 변환의 과정이 필요함.
- 특정 타입의 객체만 저장할 수 있는 컬렉션을 만들수 있고, 타입 변환 없이 객체 추출 가능.
- 이로써, 코드의 안정성과 가독성을 향상.
https://github.com/bottomsUp-99?tab=repositories
728x90
반응형
'Java Study' 카테고리의 다른 글
java.base 모듈 (0) | 2024.07.13 |
---|---|
Lamda(람다식) (0) | 2024.07.12 |
JDBC 라이브러리 (0) | 2024.07.07 |
예외 처리(Exception Handling) (1) | 2024.07.07 |
인터페이스(Interface) (0) | 2024.07.02 |