일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 코틀린
- mybatis
- JavaScript
- Spring
- error
- Vue
- db
- 자바
- kotlin
- Security
- 알고리즘
- 오라클
- 에러
- oracle
- GitHub
- 방법
- aws
- Git
- 쿼리
- 넥사크로
- 프로그래머스
- 시큐리티
- 스프링
- Java
- Eclipse
- 생성
- jquery
- 함수
- JPA
- IntelliJ
- Today
- Total
송민준의 개발노트
제네릭이란...? 본문
제네릭이란?
하나의 코드를 여러 타입에 대하여 재사용할 수 있도록 해주는 기술 중 하나임. 하남디로 클래스를 정의할 때, 구체적인 타입을 적지 않고 변수 형태로 적어 놓는 것임. 클래스를 사용하여서 객체를 생성할 때, 구쳊거인 타입을 적어주면 됨.
사용 방식 ex)
class MyClass<T> {
...
}
보면 클래스 옆에 T라고 했는데 이는 데이터의 타입을 구체적으로 적지 않고 T라고 하는 타입 매개변수로 표시하는 것임 만약에 특정 타입을 지정해주고 싶다면
class MyClass<Integer> {
...
}
위와 같이 해주면 된다.
보통 T가 들어가는 자리에 Object가 들어가야 한다고 생각할 수도 있지만 T라는 놈은 클래스 타입, 인터페이스 타입, 배열 타입 등을 나타낼 수 있음. 다만 기초 자료형은 클래스가 아니기 때문에 안되고 래퍼 클래스를 대신 넣어줘야 함. 이 외에도 제네릭 클래스는 여러 개의 타입 매개변수를 가질 수 있으나 타입의 이름은 클래스나 인터페이스에서 유일해야함. 관례에 의하여 타입의 이름은 하나의 대문자로 함. 일반적으로 많이 사용하는 타입은 아래와 같음.
1. E - Element
2. K - Key
3. N - Number
4. T - Type
5. V - Value
등등...
또한 생성자 호출 시 타입 인수를 구체적으로 안줘도 되는데 이는 컴파일러 단계에서 타입을 추측하기 때문임. 이를 다이아몬드 라고 함. 예로 아래와 같이 만들 수 있음.
MyClass<Integer> mc = new MyClass<>();
- 제네릭 클래스는 다중 타입 매개변수를 가질 수 있다고 했는데 Map을 한번 뜯어보겠다.
public interface Map<K, V> {
...
V get(Object key);
V put(K key, V value);
void putAll(Map<? extends K, ? extends V> m);
...
}
위와 같은 코드처럼 K, V를 매개변수로 받아왔고 이를 고려해 내부 코드들을 설계한 것을 볼 수 있음.
보면 " ? extends K " 같은 문법을 볼 수 있는데 이는 매개변수로 전달되는 타입의 종류를 제한 하는 것임.
예를 들어 Number이라는 클래스에 있는 메소드를 사용해야하는데 뜬금없이 String 클래스가 들어오면 사용을 못할 것임. 그러므로 이러한 종류를 제한시켜주는역할을 함.(ex. Integer, Double 등)
또한 ? 는 와일드 카드를 칭함. 와일드 카드는 어떤 타입이던지 나타낼 수 있음. 그리고 상한이 있는 것과 없는 것, 하한이 있는 것으로 구분할 수 있는데 위에 처럼 " ? extends K "의 경우 상한이 있는 것으로 구분됨. K라는 클래스를 상속받는 것으로 제한시켜주는 것으로 위에 설명과 동일함.
즉 정리를 하자면. 아래 코드의 의미는 Number클래스를 상속받는 클래스만 타입으로 올 수 있다는 것임.
Map<? extends Number>
반대로 한도가 없는 것은 모든 타입에 매치가 됨. " Map<?> "
여기서도 마찬가지로 Object 보단 ?를 쓰는 것이 올바른 경우가 있는데 목적이 모든 타입에 대해 적용하는 것일 때임.
하한이 없는 경우는 " ? super A " 와 같은 문법을 사용함. 이는 A라는 클래스의 조상 클래스들에 대하여 작동하고 싶을 때 사용한다. 예를 들어 Integer가 A일 경우 Integer, Number, Object가 가능한 것임.
그리고 V의 타입이 Integer라고 봤을 때 put을 사용하면서 '3'과 같은 숫자를 넣어주면 내부에서 오토박싱에 의하여 Integer 객체로 자동 변환되는게 있음.
혹시나 선언시 제네릭을 선언 안해주면 Object 클래스로 자동 매핑됨.
자 그럼 이를 실무에서 아주 좋게 활용한 것이 있는데
제네릭스를 이용한 상속 전략을 택해서
단순 CRUD는 추상클래스로 빼서 이를 상속받으면 중복되고 지루한 코드작성을 줄일 수 있음.
이는 다음에 한번 더 정리해 보겠음.
'JAVA' 카테고리의 다른 글
추상 클래스란 (0) | 2021.01.28 |
---|---|
기본자료형과 래퍼클래스 정리 (0) | 2021.01.12 |
JAVA에서 SFTP 활용하기!! CSV 파일 적용(JSch 사용) (0) | 2020.11.08 |
String 클래스 isEmpty 메소드 (2) | 2020.04.16 |
JavaBean (0) | 2019.11.12 |