728x90
제네릭이란
결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능
public class Box {
public ? content ;
}
- Box클래스에서 결정되지 않은 content의 타입을 T라는 타입 파라미터로 정의 <T>는 T가 파라미터임을 뜻하는 기로호 타입이 필요한 자리에 T를 사용할 수 있음을 알려주는 역할을 한다.
- Box클래스는 T를 content 필드의 사용으로 사용하였고 T가 무엇인지 모르겠지만 Box객체가 생성될 시점에 다른타입으로 대체된다는 것을 알고 있다.
public class Box <T> {
public <T> content ;
}
- Box의 내용물을 String으로 저장하고 싶다면 Box를 생설할 때 타입 파라미터 T 대신 String으로 대체하면 된다.
Box<Stirng>box = new Box<String>();
box.content = "안녕하세요.";
String content = box.content; //강제타입변환이 필요없어 "안녕하세요"를 바로 얻을 수 있음
- Box의 내용물로 100을 저장하고 싶다면 Box를 생설할 때 타입 파라미터 T 대신 Integer로 대체하면 된다. Integer는 정수값을 표현하는 클래스 타입
Box<Integer>box = new Box<Integer>();
box.content = 100;
int content = box.content; //강제타입변환이 필요없어 100dmf 바로 얻을 수 있음
<T>에서 타입 파라미터로 쓰이는 T는 단지 이름일 뿐이기 때문에 A-Z 어떤 알파벳을 사용해도 좋다.
주의할 점은 타입 파라미터를 대체하는 타입은 클래스 및 인터페이스라는 것!!
Box<int>라고 작성하지 않은 이유는 기본타입은 타입 파라미터의 대체 타입 될 수 없기 때문이다.
- 변수를 선언할 때와 동일한 타입으로 호출하고 싶다면 생성자 호출 시 생성자에는 타입명을 명시하지 않고 < >만 붙일 수 있다.
Box<Stirng>box = new Box<String>(); -> Box<Stirng>box = new Box< >();
Box<Integer>box = new Box<Integer>(); -> Box<Integer>box = new Box< >();
제네릭타입이란
결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다.
- 제네릭 타입은 선언부에 ‘ < >’ 부호가 붙고 그 사이에 타입 파라미터들이 위치한다.
- 타입 파라미터는 변수명과 동일한 규칙에 따라 작성할 수 있지만 일반적으로 대문자 알파벳 한 글자로 표현
- 외부에서 제네릭 타입을 사용하려면 타입 파라마미터에 구체적인 타입을 지정해야한다. 만약 지정하지 않으면 Object타입이 암묵적으로 사용된다.
public class 클래스명<A, B, > {.....}
public interface 인터페이스명<A, B, > {.....}
//제네릭 타입, 타입 파라미터로 K, M정의
public class Product<K, M> {
//필드, 타입 파라미터를 필드 타입으로 사용
private K kind;
private M model;
//메소드, 타입 파라미터를 리턴 타입과 매개변수 타입으로 사용
public K getKind() {return this.kind;}
public M getModel() {return thsi.model;}
public void setKind(K kind) {this.kind = kind;}
public void setModel(M model) {this.model = model;}
}
- 타입 파라미터는 기본적으로 Object타입으로 간주되므로 Object가 가지고 있는 메소드를 호출할 수 있다.
- Box의 내용물을 비교하기 위해 타입 파라미터로 Object의 equals()메소를 호출한다.
public class Box<T> {
public T content;
//Box의 내용물이 같은지 비교(content필드값 비교)
public boolean compare(Box<T> other) {
boolean result = content.equals(other.content);
return result;
}
}
제네릭 메소드
타입 파라미터를 가지고 있는 메소드. 타입 파라미터가 메소드가 메소드 선언부에 정의된다는 점에서 제네릭 타입과 차이가 있다.
- 리턴 타입 앞에 < > 기호를 추가하고 파라미터를 정의한 뒤 리턴 타입과 매개변수 타입에서 사용한다.
public <A, B, ...> 리턴타입 메소드명(매개변수, ...) {....}
// <A, B, ...> -> 타입 파라미터 정의
- boxing( )메소드는 타입 파라미터로 <T>를 정의하고 매개변수 타입과 리턴 타입에서 T를 사용한다.
public <T> Box<T> boxing(T t) {...}
- 타입 파라미터 T는 매개값이 어떤 타입이냐 따라 컴파일 과정에서 구체적인 타입으로 대체된다.
Box<Integer> box1 = boxing(100);
Box<String> box2 = boxing("안녕하세요");
제한된 타입 파라미터
모든 타입으로 대체할 수 없고 특정 타입과 자식 또는 구현 관계에 있는 타입만 대체할 수 있는 타입 파라미터를 제한된 타입 파라미터라고 한다.
- 경우에 따라 타입 파라미터를 대체하는 구체적인 타입을 제한할 필요가 있다. 예) 숫자를 연산하는 제네릭 메소드는 대체 타입으로 Number 또는 자식 클래스(Byte, Short, Integer, Long, Double)로 제한할 필요가 있다.
- 상위타입은 클래스뿐만 아니라 인터페이스도 가능하며 인터페이스라고해서 implements를 사용하지 않는다.
public <T extend 상위타입> 리턴타입 메소드(매개변수, ...) {...}
와일드카드 타입 파라미터
제네릭 타입을 매개값이나 리턴 타입을 사용할 때 타입 파라미터로 ?(와일드카드)를 사용할 수 있다. ?는 범위에 있는 모든 타입을 대체할 수 있다는 표시이다.
'java' 카테고리의 다른 글
Java | 람다식 (1) | 2023.02.02 |
---|---|
Java | 컬렉션 프레임워크 (0) | 2023.02.02 |
[java] 중첩 클래스 (0) | 2023.02.01 |