제네릭(Generic) : 클래스 내부에서 사용할 데이터 타입을 외부에서 지정. 타입을 구체적으로 지정하는 것이 아니라 추후에 지정할 수 있도록 일반화
- 객체별로 다른 타입의 자료가 저장될 수 있으며,
- 인터페이스, 클래스, 필드, 메서드, 등.. 앞에 붙어서 사용가능
- 제네릭 클래스(클래스명 <T>) : 클래스가 인스턴스화 될 때 타입 지정
- 제네릭 메서드(<T> void 메서드명) : 메서드가 호출될 때 타입 지정
public Interface InterfaceName <T> {...} //제네릭(타입의) 인터페이스
public class ClassName <T> {//제네릭 클래스
void setItem(T item) {...} //제네릭 파라미터 메소드
T getItem() {return item;} //제네릭 타입 반환 메소드
}
public class Student{ //일반 클래스
public <T> T genericMethod(T o) {...}// 제네릭 메소드
}
public class Main{
public static void main(String[] args){
ClassNmae<String> a = new ClassName<>(); //new 뒤쪽 타입 생략가능(jdk 1.7 이후)
ClassName<Student> s = new ClassName<>(); //사용자정의한 객체도 타입변수로 올수 있음
}
}
- 제네릭 타입 매개변수
- <> 다이아몬드 연산자 → 안에 식별자기호를 지정하여 파라미터화 함 ⇒ 타입 매개변수, 타입 변수
- jdk 1.7 이후부터 new 생성자 뒤에 제네릭 타입 생략 가능
- 암묵적으로 타입매개변수로 사용하는 char
- <T> Type → S, U, V..…
- <E> Element
- <K> Key, K,V
- <V> 리턴 값 또는 매핑된 값(Variable)
- <R> Result
- <N> Number
<장점>
- 컴파일 타임에 타입 검사를 통해 예외 방지
- → 타입이 지정되기 때문에 타입 안정성이 향상됨
- 불필요한 캐스팅이 없어짐
- → Object 타입 사용 시 Up/Down 캐스팅이 필요하고, 이 때 캐스팅이 잘못 되면 런타임시 오류 발생함
- 코드 재사용성이 증가함 → 타입별로 클래스/메서드 만들 필요 없음
<주의사항>
- 타입 파라미터로 명시할 수 있는 것은 참조타입(객체) 밖에 없음(원시 타입 → wrapper class로 객체로 변환필요)
- 제네릭 타입의 객체는 생성 불가(선언은 가능함)
- static 멤버에 제네릭 타입이 올 수 없음
- static 메소드는 제네릭 가능(제네릭 클래스와 별도로 독립적인 제네릭이 사용 필요)
제네릭 클래스
public class Classname<K, V>{ //제네릭 클래스 : 클래스 내부에서 사용할 타입 매개변수 선언
static V item2; //불가!!!. 클래스 변수는 타입매개변수 불가
private K item; //가능. 제네릭 타입 변수
void setItem(K item) { //제네릭 파라미터 메소드
this.item = item;
}
K getItem() { //제네릭 타입 반환 메소드
return item;
}
}
- 클래스 변수에 타입매개변수 사용 불가
- 클래스 변수 : 모든 인스턴스가 공유하는 변수 → 인스턴스 별로 달라지면? 안됨.
제네릭 메서드 : 클래스 내부의 특정 메서드만 제네릭으로 선언
[접근 제어자] <제네릭타입> [반환타입] [메소드명]([제네릭타입] [파라미터]) {...}
public class Classname<E>{ //제네릭 클래스 : 클래스 내부에서 사용할 타입 매개변수 선언
private E item; //제네릭 타입 변수
<E> E genericMethod(E o) { // 제네릭 메소드 : 제네릭 클래스의 E타입과 독립적인 타입
return o;
}
static E genericMethod(E o) { // error! : static 메소드는 객체가 생성되기 이전에 메모리에 올라갔기 때문에 E를 클래스로부터 얻어올 수 없음.
return o;
}
static <E> E genericMethod1(E o) { // 제네릭 메소드 : 제네릭 클래스의 E타입과 독립적인 타입
//**메서드 안에서 지역변수처럼 사용가능함
**return o;
}
}
- 제네릭 메서드의 타입 지정은 메서드가 호출될 때 지정(클래스명 앞에 선언한 타입 매개변수는 클래스가 인스턴스화 될 때 지정)
→ static 메서드 사용이 가능 : 제네릭 클래스와 별도로 독립적인 제네릭으로 사용해야함 - 제네릭 클래스의 타입 매개 변수와 별개 : 클래스에서 지정한 제네릭 유형과 별도로 메소드에서 독립적으로 제네릭 유형 선언하여 사용
→ <>안의 타입을 파라미터로 보내 제네릭 타입을 지정함 - 클래스에 선언된 T : 클래스 내에서 유효 // 메서드에 선언된 T : 메서드 내에서 유효 → 두개는 다름
'Coding > 언어-JAVA' 카테고리의 다른 글
JAVA 예외(try-catch) #Day7 (0) | 2023.08.11 |
---|---|
JAVA Generic 타입제한 2/2 #Day6 (0) | 2023.08.10 |
JAVA Collection Framework 2/2 #Day5 (0) | 2023.08.07 |
JAVA Collection Framework 1/2 #Day5 (0) | 2023.08.07 |
JAVA 클래스, 메서드 구성 형태 (0) | 2023.08.05 |