제네릭은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법.
class Person<T> {
public T info;
}
Person<String> p1 = new Person<String>();
public T info => public String info; 로 됨.
왜? 사용하는가
코드의 중복을 방지하고 타입의 안전성 확보를 위해
메소드 단위 제네릭
class Person {
public <U> void printInfo(U info) {
System.out.println(info);
}
}
public class GenericDemo {
public static void main(String[] args) {
Person p1 = new Person();
p1.<String>printInfo("테스트 !");
p1.<Integer>printInfo(1);
}
}
제네릭의 제한(추상 클래스)
// 부모 클래스
abstract class info {
public abstract int getLevel();
}
class EmployeeInfo extends Info {
public int rank;
EmployeeInfo(int rank){ this.rank = rank; }
public int getLevel() {
return this.rank;
}
}
class Person<T extends Info> {
public T info;
Person(T info){ this.info = info; }
}
public class GenericDemo {
public static void main(String[] args) {
Person<EmployeeInfo> p1 = new Person<EmployeeInfo>(new EmployeeInfo(1));
Person<String> p2 = new Person<String>("부장"); // 부모나 자식클래스의 타입과 일치하지 않아 에러 발생
}
}
제네릭의 제한(인터페이스)
// 부모 클래스
interface info {
public int getLevel();
}
class EmployeeInfo implements Info {
public int rank;
EmployeeInfo(int rank){ this.rank = rank; }
public int getLevel() {
return this.rank;
}
}
class Person<T extends Info> {
public T info;
Person(T info){ this.info = info; }
}
public class GenericDemo {
public static void main(String[] args) {
Person<EmployeeInfo> p1 = new Person<EmployeeInfo>(new EmployeeInfo(1));
Person<String> p2 = new Person<String>("부장"); // 부모나 자식클래스의 타입과 일치하지 않아 에러 발생
}
}
암묵적인 규칙
타입 | 설명 |
T | 타입(Type) |
E | 요소(Element), ex) List |
K | 키(Key), ex) Map<K, V> |
V | 리턴 값 또는 매핑된 값(Variable) |
N | 숫자 |
S, U, V | 2, 3, 4 번째에 선언된 타입 |
제네릭 와일드 카드
<?> : unbounded wildcards | 모든 클래스나 인터페이스 타입이 올 수 있음 |
<? extends 상위타입> : upper bounded wildcards | 상위 타입이나 상위 타입의 하위 타입만 올 수 있음 |
<? super 하위타입> : lower bounded wildcards | 하위 타입이나 하위 타입의 상위 타입만 올 수 있음 |
'Dev > JAVA' 카테고리의 다른 글
자바 JAVA 람다식 (2) | 2023.11.22 |
---|