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);
    
    제너릭을 사용할 경우 아래처럼 (String) 캐스팅이 필요없어진다
    List<String> list = new ArrayList<String>();
    list.add("hello");
    String s = list.get(0);   // no cast
    
  • 제너릭 알고리즘 사용이 가능하다.