강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

맥스님의 프로필 이미지
맥스

작성한 질문수

김영한의 실전 자바 - 중급 2편

직접 구현하는 배열 리스트5 - 제네릭2

배열에 제네릭 타입을 사용하지 못하는 이유에 대한 질문입니다.

작성

·

136

0

 학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.


1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
여기에 질문 내용을 남겨주세요.

 

1. 제네릭은 생성자를 통해 인스턴스를 생성하는 시점에 타입이 결정된다.

2. 코드로 타입 인자가 전달되면 자바 컴파일러는 제네릭 정보를 이용해서 해당 타입을 이해한다.

3. 자바 이레이져에 의해 컴파일 후 제네릭 정보가 사라진다 => 상한인 Object로 변경됨

제네릭 적용이 이런식으로 진행된다고 이해를 했습니다.
그러면 배열에 타입 인자를 적용하더라도 결국 상한인 Object로 변경되어서 코드가 돌아가지 않나요?

private E[] elementData;



public MyArrayListV4() {

   elementData = new E[DEFAULT_CAPACITY];

}

자바가 E를 알 수 없어서 사용 불가능하다는 부분이 이해가 잘 안됩니다... 제가 어떤 부분을 놓치고 있는 걸까요?

답변 2

0

안녕하세요. 디벨로퍼님, 공식 서포터즈 David입니다.

배열은 자바 초창기에 공변성을 지원하도록 설계되었습니다. 이로인해 런타임에 타입 검사가 필요합니다.

제네릭은 그 이후에 나왔는데 컴파일 타임에 타입 검사를 다 끝내고 타입정보를 모두 소거합니다.

 

자바의 배열은 공변성을 가집니다. 즉, String[]Object[]의 하위 타입이므로 다음 코드가 허용됩니다.

String[] strArray = new String[10];
Object[] objArray = strArray;

하지만 이렇게 하면 잘못된 타입이 들어갈 위험이 생깁니다.

objArray[0] = 42; // ArrayStoreException 발생!

이 문제를 막기 위해 자바는 런타임 타입 검사를 수행하여 배열의 타입을 유지하려 합니다.

런타임 타입 검사 수행을 위해서는 타입정보가 필요하고 제네릭의 타입소거가 적용된다면 타입정보가 사라지기 때문에 배열의 타입(String)에 맞는 타입 검사를 수행할 수 없게 됩니다.

따라서, 질문 주신 코드는 컴파일시 오류가 발생하게 됩니다.

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.

디벨로퍼님께서 질문하신 부분은 제네릭과 배열의 특성 차이 때문에 발생하는 혼동일 수 있습니다. 자바에서 배열과 제네릭 타입은 같은 방식으로 작동하지 않습니다. 다음은 관련된 설명과 참고할만한 답변 링크입니다.

제네릭과 배열의 차이점에 대한 설명

  1. 자바의 재너릭과 타입 소거(Type Erasure): 제네릭은 컴파일 시에만 타입 검사를 수행하고, 실행 시에는 타입 정보가 제거됩니다. 이는 타입 안전성을 제공하는 대신 array처럼 런타임에서 타입이 유지되어야 하는 구조에서는 문제를 일으킵니다.

  2. 배열의 타입 정보 유지: 배열은 생성 시점에 구체적인 타입을 알아야 하며, 이는 런타임까지 유지됩니다. 따라서 배열은 생성 시점에 해당 타입이 명확하지 않은 제네릭 타입을 사용할 수 없습니다.

  3. 제네릭 배열의 선언하는 방법: 일반적인 해법으로는 Object 배열을 사용하고, 필요한 지점에서 명시적 타입 캐스팅을 통해 해결하는 방법이 많이 사용됩니다.

다음 링크들은 제네릭 배열의 이해를 돕고 해당 사례에서 문제를 해결할 수 있는지 알려드립니다:
1. 제네릭 메서드 사용 질문
2. arrayList 다운 캐스팅 오버헤드에 대한 질문이 있습니다.

이해하기 어려운 부분이 있더라도 걱정하지 마세요! 제네릭과 배열의 개념은 익숙해지기까지 시간이 걸릴 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

맥스님의 프로필 이미지
맥스

작성한 질문수

질문하기