본문 바로가기

Web/JAVA

[Generics] 제네릭 알아보기

728x90

 

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics-%EA%B0%9C%EB%85%90-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%B3%B5%ED%95%98%EA%B8%B0

 

☕ 자바 제네릭(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>();
    }
}
// 이건 됨

 

728x90

'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