-
TIL - 제네릭(generic) 정리JAVA/자바공부 2022. 2. 4. 04:32
컬렉션 프레임 워크를 뜯어보다 generic을 모르는 것 같아 정리한다.
목차
- 제네릭스란
- 사용하는 이유
- 네이밍 컨벤션
- 제네릭 제한
제네릭스란?
자바에서 제네릭스란 데이터의 타입에 "신뢰"를 더한 다는 것을 의미한다.
- 제네릭스는 다양한 타입의 객체를 다루는 메서드나 컬렉션 클래시에 컴파일 시의 타입체크(compile-time type check)를 해주는 기능이다.
- 객체 타입의 안정성을 높이고 형변환의 번거로움이 줄어든다.
- 예를 들어 ArrayList 같은 컬렉션에 한 종류의 객체만 담기로 했다고 가정하면, 원하지 않는 종류의 객체가 포함될 가능성, 사용처에 따라서 list에서 꺼낼때마다 타입체크, 형변환 하는 불편함이 있다.
- 제네릭스를 사용하면 간결하게 해결
Class Person에 <>로 T라고 선언 해두고,
인스턴스화 할때 new Person<사용할 데이터 타입>(); 으로 하면
내부에 T 전부가 <사용할 데이터 타입>으로 바뀐다. (말이 어렵나...? 밑에 예시)
class Person<T> { public T info; } Person<String> p1 = new Person<String>(); Person<Integer> p2 = new Person<Integer>(); List<Integer> array = new ArrayList<>();
사용하는 이유
* 타입 안정성
- 데이터 타입이 다르면 컴파일 시에 오류 검출.
- 중복의 제거와 안정성을 동시에
- 타입 안정성 제공. - 타입체크, 형변환을 생략할 수 있어서 코드가 간결해진다.
사용법
- 제네릭 선언
// class Box class Box { Object item; void setItem(Object item) { this.item = item; } Object getItem() { return item; } } // 제네릭으로 선언한 Box class class Box<T> { T item; void setItem(T item) { this.item = item; } T getItem() { return item; } }
- 데이터 타입에 T(타입 변수: type variable)로 선언하면 아래와 같이 활용
Box<String> box = new Box(String); // T로 선언한 부분이 String으로 지정 box.setItem(new Object); // String 타입이 아니기 때문에 컴파일 Error 반환 box.setItem("abc"); // String 타입이므로 가능 String item = box.getItem(); // 형변환 없이 사용가능, Object 타입이었다면 캐스팅을 사용해 String item = (String) box.getItem();
- 즉, 제네릭을 사용하면 미리 선언해둔 <사용할 데이터 타입(T)>을 인스턴스화 할때 원하는 타입으로 지정해서 사용할 수 있다.
// 또 다른 예시 class Person<T> { public T info; } Person<String> p1 = new Person<String>(); Person<Integer> p2 = new Person<Integer>(); List<Integer> array = new ArrayList<>();
네이밍 컨벤션
- 다시 말해, 제네릭은 임의의 참조형 타입을 T로 선언해두고 지정해서 쓸수 있는 것.
- 이때 사용처에 따라서, 일반적으로 사용하는 네이밍 컨벤션이 있다.
- <T> : 데이터 타입 type의 첫 글자 - <E> : List<E> : 배열에 들어가는 Element의 첫 글자 - <K>, <V> : Map<K, V> : key, value 값 의미 - <N> : Numebr - <R> : Result, 리턴값 - <?> : wild card 밑에 자세히 설명 예정. <? extends Object>와 동일
제네릭 제한
- Static은 모든 객체에 동일하게 동작하기 때문에, static으로 선언된 클래스의 맴버변수는 T로 선언할 수 없다.
- 참조 타입만 사용될 수 있다. int, char 같은 기본 타입은 T로 선언할 수 없다.
- extends 키워드를 사용하면 타입 변수에 특정 타입만을 사용하도록 제한할 수 있음.
class AnimalList<T extends LandAnimal> { ... }
class AnimalList<? super LandAnimal> { // 육지 동물 부모 타입만 올 수 있음 }
와일드 카드
- <?> 오버로딩을 위해서 만들어짐 - 오버로딩 할때 제네릭의 타입만 다른 경우, 오버로딩이 아니라 메서드 중복으로 인식된다. - 컴파일러가 제네릭 타입을 컴파일 할때만 사용하고 제거해버리기 때문에, ? 와일드 카드를 사용해야한다. - <? extends T> - <? super T> - <?>
출처
https://opentutorials.org/module/516/6237
http://tcpschool.com/java/java_generic_concept
https://stackoverflow.com/questions/9921676/what-does-class-mean-in-java
- 자바의 정석 - 남궁성
반응형'JAVA > 자바공부' 카테고리의 다른 글
정규식 표현 (자바, 코틀린) - 전화번호, 우편번호, 이메일 (0) 2022.10.14 자바 17로 바꿔야 할까? (자바 JDK 10 ~ 17 정리) (1) 2022.10.01 Optional<> 과 Null (이론편) (0) 2022.07.15 TIL - Final 키워드 (3) 2022.02.11 TIL - 자바를 잡아라 (1) 2022.01.06