ordinary
[effective_java] item28, item29, item30 본문
Item28 : 배열보다는 리스트를 사용하라
Item29 : 이왕이면 제네릭 타입으로 만들라
Item30 : 이왕이면 제네릭 메서드로 만들라
Item28 : 배열보다는 리스트를 사용하라
- 배열(Array)
- 배열(array)은 같은 타입의 변수들로 이루어진 유한 집합
- 리스트(List)
- 자바에서 제공하는 인터페이스
- https://docs.oracle.com/javase/6/docs/api/java/util/List.html
배열은 공변이고 제네릭(리스트)은 불공변이다.
- https://stackoverflow.com/questions/6684493/why-are-arrays-invariant-but-lists-covariant
- Super이 Sub의 상위타입일때 Super[]은 Sub[]의 상위타입이 된다.
- 반면에, List<Type1>은 List<Type2>의 상위타입도 하위타입도 아니다.
- 예시
// 1. Array
Object[] objectArray = new Sring[2];
objectArray[0] = 1L; // ArrayStoreException 발생 (런타임시 발생하는 에러)
// 2. List
List<Object> objectList = new ArrayList<String>(); // 호환되지 않는 타입 (컴파일시 발생하는 에러)
objectList.add(2L);
배열은 실체화되지만 제네릭(리스트)은 소거된다.
- 배열 : 런타임시에도 타입을 인지함
- 제네릭 : 컴파일 시에 타입을 검사함
- 제네릭이 컴파일조차 되지 못한 타입들은 런타임까지 시점까지 존재하지 않고 소거된다
Item29 : 이왕이면 제네릭 타입으로 만들라
Object -> E로 변환
- 이 방법을 사용하면 배열 Object[] -> E[] 로 변환되는데 E는 실체화 불가 타입으로 배열을 만들 수 없어 에러가 발생한다.
- 해결책1
- elements = (E[]) new Object[10]; // 캐스팅
- @SupressWarning("unchecked") 달아주기
- 해결책 2
- 리턴값을 제네릭으로 하는 pop 메서드 사용
- E result = (E) elements[--size]; // 이것도 캐스팅
- 해결책1
stack 메서드 예제
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
for (String arg : args) {
stack.push(arg)
}
while(!stack.isEmpty() {
System.out.println(stack.pop().toUpperCase());
}
}
- 위의 예제코드에서는 toUpperCase()를 활용한 명시적 형변환을 수행했다.
다수의 제네릭타입은 기본타입은 사용 불가함
- List<int> (X)
- List<Integer> (O)
- 박싱된걸로 쓰면 된다.
매개변수에 제약을 두는 제네릭 타입
- class DelayQueue<E extends Delayed> implements BlockingQueue<E>
Item30 : 이왕이면 제네릭 메서드로 만들라
public static Set union(Set s1, Set s2) {
Set result = new HashSet(s1);
result.addAll(s2);
return result;
}
- 입력2개, 반환1개의 원소타입일 경우 컴파일 O, 경고 발생한다.
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
Set<E> result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
- 제네릭 메서드를 사용해 타입 안전하게 사용
public static void main(String[] args) {
Set<String> greeting = Set.of("안녕", "Hi", "你好");
Set<String> farewell = Set.of("잘가", "Bye", "再见");
Set<String> meeting = union(greeting, farewell);
System.out.println(meeting); //
}
- 위에서 만든 union함수를 활용하는 방법