■ Generic 이란
자바에서 제네릭(Generic)은 클래스 내부에서 사용할 데이터 타입을 외부에서 사용자에 의해 지정하는것을 의미하는것으로 객체별로 다른 타입의 자료가 저장될 수 있도록 한다
List<String> list = new ArrayList<>();
- 해당 코드에서 <> 꺾쇠 괄호가 제네릭이다, 리스트 클래스 자료형의 타입을 String 타입으로 지정되어 문자열 데이터만 List에 담을 수 있게된다
- 즉 변수를 선언할 때 변수의 타입을 지정하듯이 제네릭은 객체에 타입을 지정해주는 것이라고 생각하면 된다
// 제네릭 타입 매개변수에 정수 타입 할당
List<Integer> list = new ArrayList<>();
// 제네릭 타입 매개변수에 문자열 타입 할당
List<String> list = new ArrayList<>();
// 제네릭 타입 매개변수에 실수 타입 할당
List<Double> list = new ArrayList<>();
// 제네릭 타입 매개변수에 클래스(Soccer class가 있다고 가정) 타입 할당
List<Soccer> list = new ArrayList<>();
public class Note4<Soccer> {
List<Soccer> list = new ArrayList<>();
public void add(Soccer player) {
list.add(player);
}
}
- List<T>의 <T>는 타입 매개변수라고 부르며 제네릭을 이용한 클래스나 메소드를 설계할 때 사용된다.
- new 생성자 부분의 제네릭 타입을 생략 할 수 있다
- 제네릭에서 할당 받을 수 있는 타입은 Reference 타입 뿐이다 int, double과 같은 타입은 제네릭 타입 파라미터로 넘길 수 없다
class Soccer {}
class Tottenham extends Soccer {}
class ManCity extends Soccer {}
class Note4<T> {
List<T> player = new ArrayList<>();
public void add(T info) {
player.add(info);
}
}
public class Main {
public static void main(String[] args) {
Note4<Soccer> list = new Note4<>();
// 제네릭 타입의 다형성 원리 적용
list.add(new ManCity());
list.add(new Tottenham());
}
}
- 제네릭 타입 파라미터에 클래스 타입으로 온다는 것은 객체지향 프로그래밍의 다형성 원리가 그대로 적용된다.
- 복수로 타입을 사용할 수도 있으며 클래스 초기화할 때 제네릭 타입을 두개 넘겨주어야한다
■ Generic 사용 이유
1. 컴파일 타임에 타입 검사를 통해 미리 예외 방지
2. 불필요한 캐스팅을 없게하여 형 변환의 번거로움을 줄이고 가독성이 좋아진다
■ Generic 사용시 주의사항
1. 제네릭 타입의 객체는 생성 불가
class Note4<T> {
public void Practice() {
T t = new T();
}
}
2. static 데이터 타입에 제네릭 타입이 올 수 없다
class Note4<T> {
private String team;
private int num;
// static 메소드의 매개변수 타입으로 사용 x
public static void Practice(T n) {
}
}
static은 클래스가 동일하게 공유하는 변수로서 제네릭 객체가 생성되기 전에 이미 자료 타입이 정해져 있어야 하기 때문이다
3. 제네릭으로 배열 선언
기본적으로 제네릭 클래스 자체를 배열로 만들 수 없다, 하지만 제네릭 타입의 배열 선언은 허용된다
// 잘못된 예
class Note4<T> {}
public class Main {
public static void main(String[] args) {
Note4<Integer>[] arr1 = new Note4<>[5]; // x
}
}
// 올바른 예
class Note4<T> {}
public class Main {
public static void main(String[] args) {
Note4<Integer>[] arr1 = new Note4[5];
arr1[0] = new Note4<Integer>(); // 위에서 이미 정의했기 때문에 Integer 사용가능
arr1[1] = new Note4<String>(); // Integer가 아닌 타입은 저장 불가
}
}
■ 제네릭 활용해보기
● 제네릭 클래스
public class Note4<T> {
private T val;
// T 타입의 team 반환
public T getVal() {
return val;
}
public void setVal(T val) {
this.val = val;
}
}
public class Main {
public static void main(String[] args) throws Exception {
Note4<Integer> n1 = new Note4<>();
n1.setVal(1);
Note4<String> n2 = new Note4<>();
n2.setVal("문자열 제네릭");
}
}
● 제네릭 인터페이스
인터페이스에서도 제네릭을 적용 할 수 있으며 인터페이스를 implements 해준 클래스에서도 오버라이딩한 메소드를 제네릭 타입에 맞추어 구현해주어야한다
interface Inter<T>{
public void addVal(T t, int num);
public T getVal(int num);
}
class Note5<T> implements Inter<T> {
private T[] arr;
public Note5() {
arr = (T[]) new Object[5];
}
@Override
public void addVal(T t, int num) {
arr[num] = t;
}
@Override
public T getVal(int num) {
return arr[num];
}
@Override
public String toString() {
return "Note5 [arr=" + Arrays.toString(arr) + "]";
}
}
public class Main {
public static void main(String[] args) throws Exception {
Note5<String> note = new Note5<>();
note.addVal("인터페이스에서 활용", 4);
note.getVal(4);
System.out.println(note.toString());
}
}
■ 제네릭 타입 범위 한정
- 제네릭에 타입을 지정해줌으로서 예외에 대한 안정성을 확보하는 것은 좋지만 너무 자유롭다는 점이 있다
- 예를들어 계산기 클래스가 있는 경우 정수, 실수 구분없이 받을 수 있도록 제네릭으로 클래스를 만들어 주었을때 숫자 관련클래스 뿐만 아니라 String이나 다른 클래스도 대입이 가능하다는 문제가 있다
- 이로 인해 나온 것이 제한된 타입 매개변수<T extends [제한타입]> 이다, 다만 상속 키워드와 같지만 <> 안에 extends가 있으면 제한을 의미하고 괄호 바깥에 있으면 상속으로 볼 수 있다
class Calculator<T extends Number> {
void add(T a, T b) {}
void min(T a, T b) {}
}
public class Main {
public static void main(String[] args) {
// Number 클래스만 받도록 제한
Calculator<Number> cal1 = new Calculator<>();
Calculator<Integer> cal2 = new Calculator<>();
Calculator<Double> cal3 = new Calculator<>();
// Number 이외 오류
Calculator<String> cal4 = new Calculator<>();
}
}
Today short review
수업을 듣던 와중 강사님께서 Generic에 대한 질문을 던졌을때 더 공부해야겠다는 생각이 들어 제네릭에 대해 조금 더 공부 해보았습니다. https://inpa.tistory.com/ 님이 작성 하신 글이 정리가 잘되어 있어 많이 배웠고 인터페이스를 활용한 부분 & 타입 제한에 대해 알 수 있었습니다
'JAVA' 카테고리의 다른 글
자바 JDK 설치 및 환경변수 설정 (0) | 2023.10.23 |
---|---|
자바 JDBC (0) | 2023.10.12 |
자바 static (0) | 2023.10.10 |
자바 인터페이스(Interface) (0) | 2023.10.06 |
자바 상속 extends (0) | 2023.09.29 |