언어/Effective Java

이펙티브 자바 Item29 - 이왕이면 제네릭 타입을 사용하라

now0204 2024. 6. 4. 14:37

 

Object배열로 이루어진 스택 

 

public class ArrayStack {
    private Object[] elements;
    private int size;

    public ArrayStack() {
        this.elements = new Object[10];
    }

    public void push(Object obj) {
        elements[size++] = obj;
    }

    public Object pop() {
        if (size == 0) {
            throw new IllegalArgumentException("스택에 아무것도 없습니다");
        }
        Object result = elements[--size];
        elements[size] = null;
        return result;
    }

}
  • 클라이언트는 이를 사용하기 위해서 매번 형변환을 해야한다. 또한 형 변환이 성공한다는 보장도 없다. 

이를 제네릭으로 바꾸며 제네릭의 장점을 알아보자 

 

먼저 모든 Object를 제네릭 E로 변경하면 컴파일 에러가 발생한다. 

public GenericStack(){
	this.elements = new E[10];
}
  • E는 소거되기 때문이다! 
 public GenericStack() {
     this.elements = (E[])new Object[10];
 }
  • E와 같은 실체화 불가 타입은 배열 생성이 안됨~~!
  • 아래와 같이 우회할 수 있다. - 필드에 E 배열 타입을 가지고 있음으로써 이 Stack은 E 타입의 인스턴스만 받을 수 있음을 확신할 수 있다. 
  • 다만, 힙오염, 런타임타입 E 컴파일 타입 Object
    • 런타임과 컴파일타임 타입이 다르면 Unchecked Warning과 ClassCastException이 발생할 가능성이 있는 상황
Set s = new TreeSet<Integer>();
      Set<String> ss = s;            // unchecked warning
      s.add(new Integer(42));
  • @SupressWarnings를 추가해서 warning을 잡을 수 있다. 

 

 

결론적으로 기존 타입 중 제네릭이 있어야 하는게 있다면, 제네릭 타입으로 변경하자


참고자료

https://javabom.tistory.com/38

 

[아이템 29] 이왕이면 제네릭 타입을 사용하라

요약 클라이언트가 사용할 때 매번 형변환을 해야하고 그 과정에서 Runtime 에러가 나는 것을 방지하기 위해 이왕이면 제네릭 타입으로 만들자. Object 배열로 이루어진 스택 public class ArrayStack { priv

javabom.tistory.com

 

https://velog.io/@injoon2019/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%EC%9E%90%EB%B0%94-%EC%95%84%EC%9D%B4%ED%85%9C-29.-%EC%9D%B4%EC%99%95%EC%9D%B4%EB%A9%B4-%EC%A0%9C%EB%84%A4%EB%A6%AD-%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EB%9D%BC

 

[이펙티브 자바] 아이템 29. 이왕이면 제네릭 타입으로 만들라

Object 기반 스택 - 제네릭이 필요하다 이 클래스에는 제네릭 타입이어야 한다. 지금은 클라이언트가 스택에서 꺼낸 객체를 형변환 해야하는데, 이때 런타임 오류가 날 위험이 있다. 클래스 선언

velog.io