1223

[Java] 제네릭 배열을 생성하지 못하는 이유 본문

Java

[Java] 제네릭 배열을 생성하지 못하는 이유

disambur23 2022. 2. 5. 18:18

제네릭과 배열의 차이점

1. 배열은 공변, 제네릭은 무공변

공변이란?

https://disambur23.tistory.com/20

 

[Java] 공변

1. 공변의 성질 공변(Variance) A가 B의 하위 타입일 때, T가 T의 하위 타입 extends Read 조상관계는 공통부분이므로 적어도 조상타입은 읽을 수 있다. 자식관계끼리는 읽을 수 없다. Write 어떠한 경우에

disambur23.tistory.com

 

  • 배열
    • Child가 Parent의 하위 타입이면, Child[]는 Parent[]의 하위 타입이다.
    • 공변
  • 제네릭
    • Child가 Parent의 하위 타입이면, ArrayList<Child>는 ArrayList<Parent>의 하위 타입이다.
    • 무공변
    • ? extends, ? super를 사용해서 공변의 성질을 사용할 수 있지만, 작업에 제한이 있다.
ArrayList<Object> objectList = new ArrayList<String>(); // 에러
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
ArrayList<? extends Object> objectList = new ArrayList<String>();

 

 

2. 배열은 런타임에 실체화, 제네릭 타입은 런타임에 소거된 상태

  • 배열
    • 배열은 런타임에 타입이 실체화된다.
Object[] obj = new Integer[1];

Object는 런타임 시에 Integer로 실체화된다.

 

  • 제네릭
    • 제네릭 타입은 컴파일 시의 타입 체크를 하며 타입이 소거되고 젠네릭 부분이 없어진다.
// 컴파일 타임(실제 작성한 코드)
ArrayList<String> stringList = new ArrayList<String>();
ArrayList<Integer> integerList = new ArrayList<Integer>();

// 런타임(제네릭 타입은 런타임에 소거되므로 구분이 불가능하다)
ArrayList stringList = new ArrayList();
ArrayList integerList = new ArrayList();

 

 

※ 제네릭 배열을 사용하려면?

1. 와일드카드 타입을 이용한 제네릭 배열 생성

  • 비한정적 와일드카드 타입은 모든 제네릭 타입을 가질 수 있다.
    • 공변성 문제되지 않는다.
// 컴파일 에러가 발생 안함.
List<?>[] lists = new List<?>[2];
lists[0] = Arrays.asList(1);
lists[1] = Arrays.asList("A");
    for (List<?> list : lists) {
        System.out.println(list);
    }
}

 

2. 형변환 이용하기

  • Object 배열에서 (E[])로 형변환을 이용하면 제네릭 배열을 만들 수 있다.
public class GQueue<E> {
    private int max; //큐의 용량
    private int front; //첫 번째 요소 커서
    private int rear; //마지막 요소 커서
    private int num; //현재 데이터 수
    private E[] que; //큐 본체
    //큐가 비었을 때나 가득 찼을 때 모두 front = rear이므로
    //구분을 하기 위해 max와 num이 필요하다.

    //생성자
    @SuppressWarnings("unchecked")
    public GQueue(int capacity) {
        num = front = rear = 0;
        max = capacity;
        try {
            que = (E[])new Object[max]; //큐 본체용 배열을 생성성
        } catch (OutOfMemoryError e) { //생성할 수 없음
            max = 0;
        }
    }
}

 

 

'Java' 카테고리의 다른 글

[Java] 공변  (0) 2022.02.05
[Java] nextInt vs nextLine 입출력 주의사항  (0) 2022.01.08
Comments