스프링을 본격적으로 사용하기 시작한지도 4년이 다 되어 가네요.
그럼에도 여전히 볼 때마다 멈칫하게 되는 부분이 있어요.
바로 자바의 제네릭(Generic) 문법이예요.
public interface MemberRepository extends CrudRepository<Member, Long> {
Optional<Member> findById(String id);
Optional<Member> findByEmail(String email);
Optional<Member> findByMemberNo(long memberNo);
}
원래 쓰던대로 그러려니 하고 개발을 할 수도 있겠지만 마음 한구석 찜찜함은 가시질 않네요.
그래, 개발자라면 본인이 사용하는 문법에 대해 기본적인 내용은 알아야지..!
그래서 자바 제네릭을 파헤쳐보기로 마음먹었어요.
1. 제네릭은 왜 만들어졌을까
제네릭을 본격적으로 파헤치기 전에 먼저 제네릭이 왜 만들어진 것인지 이 부분을 짚고 넘어가보려해요.
제네릭은 JDK 1.5 에 처음으로 추가되었어요.
그렇다면 JDK 1.5 이전에는 제네릭이 없었다는 것이고, 개발상 어떠한 문제점이 있었기 때문에 제네릭이라는 기능이 추가되었을 거라고 생각되요.
그러면 무엇이 문제가 되었길래 제네릭이라는 기능이 추가된걸까요?
먼저 아래 코드를 볼게요.
public class Main {
public static void main(String[] args) {
runCastingException();
}
private static void runCastingException() {
List list = new ArrayList();
list.add("hello");
int number = (Integer)list.get(0);
System.out.println(number);
}
}
위 코드를 실행시키면 아래와 같은 에러가 발생해요.
List 에 String 타입으로 데이터를 추가했는데 Interger 타입으로 꺼내면서 형변환(Casting) 에러가 발생한 거예요.
바로 이것이 제네릭을 사용하는 이유예요.
잘못된 타입 사용으로 발생할 수 있는 런타임 타입 에러를 컴파일 과정에 검출하는 것이 그 목적이라 할 수 있어요.
그렇다면 만약 위 코드에 제네릭을 사용한다면 어떻게 바뀔까요?
아래는 위의 형변환 에러 예시에서 제네릭만 적용한 코드예요.
List 클래스에 <String> 제네릭이 적용되니까 잘못된 구현 코드가 검출되는 것을 확인할 수 있어요.
에러 메시지에서 알 수 있듯이 String 타입을 Integer 타입으로 형변환 할 수 없다는 내용이예요.
그러면 제네릭 클래스를 직접 만들어서 사용할 수는 없을까요?
2. 제네릭 클래스를 사용해보자
아래는 제네릭 클래스 코드예요.
public class Box<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
여기서 T는 클래스 객체 생성시 전달하는 Type 을 의미해요.
Box 제네릭 클래스를 사용해볼께요.
public class Main {
public static void main(String[] args) {
runGenericClass();
}
private static void runGenericClass() {
Box<String> stringBox = new Box<>();
stringBox.set("stringBox");
System.out.println(stringBox.get());
Box<Integer> integerBox = new Box<>();
integerBox.set(723);
System.out.println(integerBox.get());
Box<Double> doubleBox = new Box<>();
doubleBox.set(901.586);
System.out.println(doubleBox.get());
Box<Boolean> booleanBox = new Box<>();
booleanBox.set(true);
System.out.println(booleanBox.get());
}
}
터미널에 출력 값이 잘 나오는 것을 확인할 수 있어요.
Box 클래스 객체를 생성할 때 제네릭 타입을 앞단에 명시해주면 new 구문에서는 생략해도 되요.
아래는 제네릭을 공부하기 위해 생성한 Git 레포지토리인데요.
코드는 여기로 들어가셔서 보실 수 있어요.
3. 앞으로 더 알아볼 제네릭 내용들
앞서 제네릭 클래스에 대해 알아보았는데요.
이 외에도 아래와 같은 내용에 대해 더 알아보려 해요.
- 제네릭 메소드 (Generic Method)
- 제네릭 인터페이스 (Generic Interface)
- 제네릭 와일드카드 (Generic Wildcard)
그 밖에 제네릭과 관련한 세부 내용들이 많겠지만 우선은 제네릭에 대한 큼직한 개념을 먼저 잡으려해요.
차근차근히 제네릭에 대해서 알아가보도록 해요.
끝까지 읽어주셔서 감사해요.
'프로그래밍 > Java' 카테고리의 다른 글
자바 제네릭 파헤치기 - Generic Interface (0) | 2023.07.22 |
---|---|
자바 제네릭 파헤치기 - Generic Method (0) | 2023.07.22 |
[Effective Java 3/E] 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2023.07.16 |
[Effective Java 3/E] 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2023.07.15 |
한글 Levenshtein Distance 구현 (0) | 2022.01.25 |