public class Generic<T> { //제네릭 클래스 - 원시타입 (T : 타입변수)
private T t;
// 객체의 static 멤버에는 사용불가
// : 타입 변수는 인스턴스 변수로 간주되어서
// 모든 객체에 동일하게 동작해야 하는 static 필드 특성상 사용불가
public T get() {
return this.t;
}
public void set(T t) {
this.t = t;
}
public static void main(String[] args) {
// 인스턴스를 만들기 위해 타입 변수에 들어갈 실제 변수의 값을 넣어줌(String)
// 기본 타입 사용불가 -> 기본타입에 해당하는 Wrapper 클래스 사용할 것!
Generic<String> stringGeneric = new Generic<>();
// 타입 변수로 대체해뒀던 곳에 String이 들어가 있기 때문에 사용가능
stringGeneric.set("Hello World");
String tValueTurnOutWithString = stringGeneric.get();
System.out.println(tValueTurnOutWithString);
}
}
제네릭 사용을 통하여 타입 언어에서 “중복되거나 필요 없는 코드를 줄이면서 타입 안정성을 해치지 않을 수 있음!"
다수의 타입변수 사용 가능
다형성(상속과 타입의 관계)는 그대로 적용되며, 와일드카드를 통해 제네릭의 제한을 구체적으로 정할 수 있음
<? extends T> : T와 그 자손들만 사용 가능
<? super T> : T와 그 조상들만 가능
<?> : 제한 없음
제네릭 배열은 생성불가
제네릭은 클래스 또는 메서드에 사용가능
제네릭 클래스 (원시 타입)
클래스 이름 뒤에 <> 문법 안에 들어가야 할 타입 변수를 지정.
선언해둔 타입변수는 해당 클래스 내에서 특정한 타입이 들어갈 자리에 대신 들어갈 수 있음
제네릭을 통해 구현한 클래스를 사용 시, 인스턴스를 만들기 위해서 타입 변수에 들어갈 실제 변수의 값을 넣어줘야함
객체의 static 멤버에 사용불가 (타입 변수는 인스턴스 변수로 간주되기 때문에, 모든 객체에 동일하게 동작해야하는 static필드특성상 사용불가)
메서드를 스코프로 제네릭을 별도로 선언가능
static <T> void sort(List<T> list, Comparator<? super T> c) { ... }
- 반환타입 앞에 <> 제네릭 사용시, 해당메서드에만 적용되는 제네릭 타입변수 선언 가능
- 타입변수를 클래스 내부의 인스턴스 변수 취급하기 때문에 제네릭 클래스의 타입 변수를 static 메서드에서는 사용할 수 없지만, 제네릭 메서드의 제네릭 타입변수는 해당 메소드에만 적용되기 때문에 메소드 하나를 기준으로 선언하고 사용가능
- 같은 이름의 변수를 사용했더라도 제네릭 메소드의 타입변수와 제네릭 클래스의 타입변수는 다르다
★ 제네릭 활용한 클래스/메서드 사용 시 제네릭의 타입 인수로는 기본 타입(primitive type) 사용 불가! 대신 기본 타입에 해당하는 Wrapper 클래스를 사용해야함 ★