☕ 자바 제네릭(Generics) 개념 & 문법 정복하기
제네릭 (Generics) 이란 자바에서 제네릭(Generics)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. 객체별로 다른 타입의 자료가 저장될 수 있도록 한다. 자바에서 배
inpa.tistory.com
제네릭 : 클래스 내부에서 사용할 데이터타입을 외부에서 지정하는 기법이다.
각 객체별로 다른 타입의 자료가 저장될 수 있도록 해준다.
ArrayList<String> list = new ArrayList<>();
<> => 이게 바로 제네릭이고 이 괄호안에는 타입명을 작성한다
꺽쇠 안에 제네릭을 지정하면 해당 타입으로 지정되어 해당 타입의 데이터만 리스트에 사용할 수 있다.
String[] array = new String[];
// 배열자료형
ArrayList<String> list = new ArrayList<>();
// 리스트자료형
제네릭은 객체(Object)에 타입을 지정해준다
< > 이 키워드는 다이아몬드 연산자라고 부르며, 식별자 기호를 지정하여 파라미터화 한다
List<T>
//타입매개변수
List<String> stringList = ...
//매개변수화된 타입
타입 파라미터 정의
- 제네릭을 이용하여 클래스나 메소드를 설계할 수 있다
class FruitBox<T> {
List<T> fruits = new ArrayList<>();
public void add(T fruit) {
fruits.add(fruit);
}
}
// 제네릭 타입 매개변수에 정수 타입을 할당
FruitBox<Integer> intBox = new FruitBox<>();
// 제네릭 타입 매개변수에 실수 타입을 할당
FruitBox<Double> intBox = new FruitBox<>();
// 제네릭 타입 매개변수에 문자열 타입을 할당
FruitBox<String> intBox = new FruitBox<>();
// 클래스도 넣어줄 수 있다. (Apple 클래스가 있다고 가정)
FruitBox<Apple> intBox = new FruitBox<Apple>();
// 다음과 같이 new 생성자 부분의 제네릭의 타입 매개변수는 생략할 수 있다.
FruitBox<Apple> intBox = new FruitBox<>();
출처: https://inpa.tistory.com/entry/JAVA-☕-제네릭Generics-개념-문법-정복하기 [Inpa Dev 👨💻:티스토리]
타입 파라미터 할당 가능 타입
제네릭에서 할당 받을 수 있는 타입은Reference 타입 뿐이다. 즉, int형 이나 double형 같은 자바 원시 타입(Primitive Type)을 제네릭 타입 파라미터로 넘길 수 없다
// 기본 타입 int는 사용할 수 없다
List<int> intList = new List<>();
// Wrapper 클래스로 넘겨주어야 한다. (내부에서 자동으로 언박싱되어 원시 타입으로 이용됨)
// Integer 는 null을 허용한다 <참고>
List<Integer> integerList = new List<>();
복수 타입 파라미터
클래스 초기화 시엔 당연히 제네릭 타입 두개를 넘겨줄 것
import java.util.ArrayList;
import java.util.List;
class Apple {}
class Banana {}
class FruitBox<T, U> {
List<T> apples = new ArrayList<>();
List<U> bananas = new ArrayList<>();
public void add(T apple, U banana) {
apples.add(apple);
bananas.add(banana);
}
}
public class Main {
public static void main(String[] args) {
// 복수 제네릭 타입
FruitBox<Apple, Banana> box = new FruitBox<>();
box.add(new Apple(), new Banana());
box.add(new Apple(), new Banana());
}
}
중첩 타입 파라미터
public static void main(String[] args) {
// LinkedList<String>을 원소로서 저장하는 ArrayList
ArrayList<LinkedList<String>> list = new ArrayList<LinkedList<String>>();
LinkedList<String> node1 = new LinkedList<>();
node1.add("aa");
node1.add("bb");
LinkedList<String> node2 = new LinkedList<>();
node2.add("11");
node2.add("22");
list.add(node1);
list.add(node2);
System.out.println(list);
}
// [[aa,bb]],[[11,22]]
출처: https://inpa.tistory.com/entry/JAVA-☕-제네릭Generics-개념-문법-정복하기 [Inpa Dev 👨💻:티스토리]
타입 파라미터 기호 네이밍
타입 | 설명 |
<T> | 타입(Type) |
<E> | 요소(Element), 예를 들어 List |
<K> | 키(Key), 예를 들어 Map<k, v> |
<V> | 리턴 값 또는 매핑된 값(Variable) |
<N> | 숫자(Number) |
<S, U, V> | 2번째, 3번째, 4번째에 선언된 타입 |
제네릭을 사용하는 이유1. 컴파일 타임에서 타입 검사를 하여 예외방지2. 불필요한 캐스팅을 없애 성능을 향상시킴
단 주의할 점1. 제네릭 타입의 객체는 생성할 수 없다
class Sample<T> {
public void someMethod() {
// Type parameter 'T' cannot be instantiated directly
T t = new T();
}
}
2. static 에 제네릭 타입은 올 수 없다
static 은 제네릭 객체 생성 전에 이미 자료타입이 정해져있어야하기 때문이다
제네릭 배열 선언시 주의점
1. 기본적으로 제네릭 클래스 자체는 배열로만들 수 없다. 하지만 제네릭 타입의 배열 선언이 가능하다.
class Sample<T> {
}
public class Main {
public static void main(String[] args) {
Sample<Integer>[] arr1 = new Sample<>[10];
}
}
// 이건 안됨
class Sample<T> {
}
public class Main {
public static void main(String[] args) {
// new Sample<Integer>() 인스턴스만 저장하는 배열을 나타냄
Sample<Integer>[] arr2 = new Sample[10];
// 제네릭 타입을 생략해도 위에서 이미 정의했기 때문에 Integer 가 자동으로 추론됨
arr2[0] = new Sample<Integer>();
arr2[1] = new Sample<>();
// ! Integer가 아닌 타입은 저장 불가능
arr2[2] = new Sample<String>();
}
}
// 이건 됨
'Web > JAVA' 카테고리의 다른 글
[비교] Object.equals() 와 equals() (1) | 2023.11.26 |
---|---|
[단일요소배열] Collections.singletonList 와 Arrays.asList (1) | 2023.11.25 |
SpringTokenizer (0) | 2023.10.19 |
데이터 구조 (1) | 2023.10.19 |
[Java Stream] skip() vs limit() (0) | 2023.04.23 |