Java/이론&문법
자바 Generic
Bubbles
2023. 9. 22. 03:06
- Java 5에서 추가
- 타입 형 변환에서 발생할 수 있는 문제점을 사전에 없애기 위해(컴파일 시점에) 만들어졌다.
- 데이터 타입을 외부에서 지정한다.
🧐 그냥 모든 객체의 최상위인 Object로 쓰긴 어려운가?
- 어떤 타입을 넘겨도 상관없지만, get으로 저장된 값을 꺼낼 때 Object로 넘어오기 때문에 형변환을 해줘야 한다.
- 이 케이스 별로 if ( ~~instanceOf String) 이런식으로..
String str = (String) data.getObject(); // data.getObject()의 리턴값이 Object이므로
String str = data.getObject(); // String으로 받겠다고 명시해놨으므로 이때 String으로 명시
그래서 등장한 것이 제너릭.
- 형 변환에서 발생할 수 있는 문제점을 사전에(컴파일 시 점검하도록) 없애기 위해서 만들어졌다.
- 아래처럼 클래스를 선언해주면 일일이 형 변환할 필요가 없다.
public class Main<T> {
private T object;
public void setObject(T obj) {
this.object = obj;
}
private T getObject(T obj) {
return obj;
}
}
// 생성 예
Main<String> dto1 = new Main<String>();
dto1.setObject(new String());
Main<StringBuffer> dto2 = new Main<String>();
dto2.setObject(new StringBuffer());
// 사용 예, 형 변환이 필요 없음, 여기서 형을 다르게 꺼내면 컴파일 단계에서 잡힌다.
String one = dto1.getObject();
StringBuffer two = dto2.getObject();
wildCard : <?>
public class Main<W> {
private W object;
public void setObject(W obj) {
this.object = obj;
}
private W getObject(W obj) {
return obj;
}
}
public void print(Main<?> m) {
Object value = m.getObject(); // wild card Object로 정함
// 이렇게 하면 어떤 타입이 제너릭이 되어도 상관없다. 대신 받을 때는 Object로만 받을 수 있음
}
- 와일드카드는 메소드 매개변수로만 사용
- 어떤 객체를 wildCard로 선언하고 값을 가져오는건 가능, 하지만 특정 타입으로 값을 지정하는 것은 불가능하다.
- ? extends XXX 이런식으로 제네릭 타입으로 XXX를 상속받은 모든 클래스를 사용할 수 있다는 의미
오라클 JDK 문서에서는 제너릭을 사용하는 이유에 대해 아래와 같이 정의한다.
- 컴파일 시점에 엄격한 타입 체킹 가능
- 불필요한 캐스팅 코드 제거 가능
List list = new ArrayList(); list.add("hello"); String s = (String) list.get(0);
List<String> list = new ArrayList<String>(); list.add("hello"); String s = list.get(0); // no cast
- 제너릭 알고리즘 사용이 가능하다.