자바 제네릭 지우개
참고
저자 임백준, 한빛미디어, 폴리글랏 프로그래밍 Chapter1.
http://stackoverflow.com/questions/11496705/instanceof-with-generic-collection
http://www.artima.com/weblogs/viewpost.jsp?thread=208860
http://rgomes-info.blogspot.kr/2013/12/using-typetokens-to-retrieve-generic.html
코드
Apple.java
package tested; public class Apple extends fruit{ public Apple() { } }
fruit.java
package tested; public class fruit { public fruit() { } }
test.java
package tested; import java.util.ArrayList; import java.util.List; public class test { public static void main(String args[]) { fruit apple = new Apple(); if (apple instanceof Apple) System.out.println("요미요미~"); if (apple instanceof List<Apple>) System.out.println("요미요미~"); } }
위의 코드를 실행 시 에러가 뜬다.
apple instanceof List<Apple>
Cannot perform instanceof check against parameterized type List<Apple>. Use the form List<?> instead since further generic type information will be erased at runtime
"런타임 시 type 정보가 지워지기 때문에, List<?> 사용해라.
List<?> 하는 순간 제네릭의 의미가 상실되지 않나... 생각한다..
List<?>는 List<? extends Object>라 이해하면 되겠다. Object는 모든 클래스 중 최상위 클래스다.
위의 ?는 공변성, 반공변성 또는 리플렉션 API에 대해 포스팅 할 때 다루겠다.
이런 현상으로 인하여 자바 제네릭은 여러 개발자에게 많은 욕을 잡수셨다.
C#의 경우, IL로 컴파일되어 => CLR 위에서 바이너리로 컴파일: 제네릭 타입은 여전히 상주한다.
즉 C#은 런타임 시 제네릭 정보를 지속적으로 보유하고 있다.
또한 제네릭 사용으로의 코드 간결화, 성능 개선의 이점을 확보한다.
여기까지 임백준 작가님의 책 내용이다.
(좀 더 풍부하지만, 깊은 내용과 관련된 내용은 독서하는 것을 추천한다.
추가적으로 알아보자
예로 ArrayList<String>을 할 경우, 자바 런타임에서는 new ArrayList() 객체 생성한다.
그리고 컴파일을 할 때 타입을 잃어버린다.
자바는 설계상 바이트 코드로 컴파일 할 경우, 모든 타입 정보를 드랍시킨다. 그 이유는 자바 소스 코드와 바이트 코드의 버전 호환을 위해서다. 그래서 결국 제네릭도 똑같이 타입 정보를 드랍한다. 이러한 사항에서의 이점은 런타임 오버 헤드를 발생하지 않는다.
(C#의 경우, 이런 문제를 해결하기 위해 CLR 자체를 수정했지만, 자바는 하지 않았다.)
그러나 모든 경우 타입 정보를 드랍하는 것은 아니다. 익명 클래스를 사용할 경우, 타입 정보를 보존할 수 있다.
그 다음은 귀찮다. 담주나 주말에 게시글 수정하겠다.
ㅇㅇ
'개발관련 > (과거)메모' 카테고리의 다른 글
Log4j 2 Manual - Introduction (0) | 2017.04.29 |
---|---|
자바 웹 서버(톰켓, 카탈리나, 재스퍼) (0) | 2017.04.03 |
자바 Keytool(셀프 사인) Server/Client 소켓 통신 방법 (0) | 2017.03.31 |
로그 간단한 개념 및 라이브러리 (0) | 2017.03.30 |
오픈소스 ERD툴: ERMaster (0) | 2017.03.30 |