❑ 제네릭(Generic)
➤ 제네릭이 무엇인가?
- Generic 은 “일반적인”이란 뜻
- 클래스 내부에 사용할 타입을 외부에서 파라미터 형태로 지정
- 데이터 타입을 일반화 ( ▶️ 범용적으로 사용할 수 있게함)
- 자바 5부터 제네릭 추가됨
➤ 제네릭 프로그래밍
어떤 변수가 하나의 참조 자료형이 아닌 여러 참조 자료형을 사용할 수 있도록 프로그래밍하는 것
여러 참조 자료형이 쓰일 수 있을 때 미리 특정한 자료형을 지정하지 않고 제네릭으로 선언해서 클래스나 메소드가 사용되는 시점에 어떤 자료형 사용할지 지정됨
➤ 제네릭 클래스 정의하기
클래스명 <T> {
}
ex)
class GenericDeclaration <T> {
private T variable;
public T getVariable() {
return variable;
}
public void setVariable(T variable) {
this.variable = variable;
}
}
여러 자료형으로 바꾸어 사용할 부분에 자료형 대신 T 작성
<> : 다이아몬드 연산자
T를 자료형 매개변수(Type parameter, 타입 매개변수)
T : 대입된 자료형
GenericDeclaration <T> : 제네릭 자료형, 매개변수화된 자료형
ArrayList<Integer> array = new ArrayList<>();
선언하는 부분의 <>에 자료형을 작성했기 때문에 생성부분의 <> 안은 생략 가능
컴파일러가 유추 가능하기 때문
주로 <>안에 T를 많이 사용 (Type)
E (Element), K (Keyt), N (Number), V (Value), R (Result) 등 있음
위의 예시 뿐만 아니라 A, B, C 등 사용자가 정의해서 사용해도 된다.
⤵️아래는 저의 견해입니다.
타입 매개변수는 수학의 변수 x라고 생각해주면 코드를 작성하고 읽기가 용이하다.
수학에서 변수 x는 어떤 수든 대입할 수 있다.
하지만 식에서 x에 특정 수를 대입하는 순간 식 안의 모든 x는 그 수로 정해져서 계산된다.
예를 들어서 x+1-2x 라는 식이 있다고 가정해보자.
이때 x에 1을 대입하려고 하면 x, -2x 모두 x=1을 대입하고 계산해야 한다.
x에는 x=1 을 대입하고 -2x에는 x=2를 대입하는 식으로 계산해선 안된다.
변수 x는 같은 수를 의미하므로 모든 x엔 같은 수로 대입해줘야 한다.
프로그래밍에서 제네릭을 컴파일하는 과정에서도 마찬가지이다.
컴파일러는 같은 알파벳의 타입 매개변수는 모두 같은 변수라고 생각한다.
따라서 타입 매개변수 T는 인스턴스가 만들어질 때 같은 타입이 대입된다.
➤ static 변수와 타입 매개변수
static 변수, static 메소드 내에서는 타입 매개변수 사용할 수 없음
🔎 이유는?
제네릭의 타입이 정해지는 것은 인스턴스가 생성되는 순간이다.
하지만 static은 클래스 생성 시 클래스 정보와 함께 메모리에 올라가는데 타입을 지정해주지 않으면 메모리를 할당할 수 없다.
따라서 타입 매개변수의 자료형이 결정되는 시점보다 static 변수나 메소드가 생성되는 시점이 더 빠르기 때문에 문제가 발생하게 된다.
➤ 왜 제네릭이 직접 형 변환하는 것보다 안정적일까?
Object 등의 상위 클래스 타입으로 정의하고 직접 형변환 해주면 제네릭보다 불안정함
제네릭 클래스는 컴파일러가 일단 대입된 자료형이 잘 쓰였는지 확인하고
class 파일을 생성할 때 타입 매개변수를 사용한 곳에 지정한 자료형에 따라 컴파일함
➤ 제네릭 메소드(Generic Method)
클래스 전체가 아닌 클래스 내부의 특정 메소드만 제네릭으로 선언
매개변수나 메소드 시그니처에 타입 매개변수 T를 사용한 메소드
메소드가 호출되는 시점에 제네릭 타입이 결정됨
정의되는 시점에는 어떤 타입이 입력되는지 알 수 없음
-> length()와 같은 클래스내 메소드는 정의하는 시점에 사용 불가
-> 최상위 클래스 Object의 메소드는 사용 가능
일반 메소드, static 메소드에서 모두 활용 가능
➤ 제네릭의 장점
- 여러 참조 자료형마다 코드를 작성하지 않아도 되서 코드가 간결하고 직관적
- 매번 형 변환을 할 필요가 없기 때문에 오류의 확률 줄어듬 -> 안정성
- 새로운 자료형을 사용할 땐 그 자료형만 생성하고 사용할때 <> 안에 자료형 넣기만 하면됨
☑️ 참고) 제네릭으로 자료형 추론하기
자바10 부터는 지역변수에 한해서 자료형을 추론 가능(var형 사용 가능)
➡️ 지역 변수 자료형 추론(local variable type inference)
var local = new ArrayList<String>();
➡️ 컴파일러가 자료형 추론 가능
➤ 와일드카드(wild card)
제한을 두지 않는 기호를 의미
제네릭에서는 ? 기호를 사용하여 와일드 카드 사용
- <?> : 타입 매개변수에 모든 타입 사용
- <? extends T> : T 타입과 T타입의 하위 클래스만 사용
- <? super T> : T 타입과 T 타입의 상위 클래스만 사용
추가로 공부할 부분
왜 Object가 아닌 Generic을 사용하는가?
Object의 메소드
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
읽어주셔서 감사합니다 😊 도움이 되셨길 바랍니다.
오개념에 대한 지적은 언제나 환영입니다.
'TIL(Today I Learned)' 카테고리의 다른 글
5/19 (목) Java 심화-1️⃣ Enum, Annotation (0) | 2022.05.20 |
---|---|
5/18 (수) 자바-내부 클래스(Inner Class) (0) | 2022.05.18 |
5/16 (월) 자바 코딩과 여러가지 오류,, (0) | 2022.05.16 |
5/13 (금) 자바 다형성 (0) | 2022.05.13 |
5/12 (목) 자바 상속(Inheritance) (0) | 2022.05.12 |