JAVA generic의 특성상, generic이 method에 붙어 있지 않는 이상 T는 컴파일 타임에 사라집니다.
무슨 뜻이냐면, compile time에 자기 할 일을 다 할 수 잇는
T t;
new ArrayList;
T[] t;
와 같은 문장 이외에
new T();
new T[3];
T.someStaticMethod();
와 같은 문장들은 사용할 수 없습니다.
크게 두 가지 방법이 있는데, 첫번째는 NumberList 생성자를
NumberList(...(기존의 parameter), Class orgclass){
// orgclass 저장
}
와 같이 만들고, exec에서
orgclass.getField("SIZE").getInt(null);
와 같이 실행하면 됩니다.
두 번째는, NumberList라 했으니 저장된 element[i]에 대해
element[i].getClass().getField("SIZE").getInt(element[i]);
와 같이 reflection을 실행하는 것입니다.
이걸 type erasure라고 부르고
이런 이상한(?)게 도입된 이유는 자바 1.5 이전 버전 (정확히 말해 이전 JVM)과의 호환성 때문이었습니다.
(기억이 맞다면) 실제 바이너리 코드상으로는 자바 1.5 이전처럼 (모든 클래스가 Object를 상속하니까) casting 을 합니다.
즉 List l 은 사용되는 곳에서 (String)l 로 casting 됩니다.
그런데 일견 잘못된 선택 같아 보이는 이게 또 웃긴게
Java에서 컴파일 때 casting 되고 class 에 metadata좀 심는것 이외에
사실 JVM 레벨에서 polymorphism 에 대해 뭘 딱히 강제하지 않기 때문에
JVM을 쓰는 다른 언어들이 각각 type에 관해 하고싶은 일을 하는데 수월하다고 하더군요.
sizeof 1:1은 없지만 제너릭 없을때 사용하던 방법도 있습니다.
sizeof 1:1은 없지만 제너릭 없을때 사용하던 방법도 있습니다.
instanceof 라는것을 사용하는것입니다.
sizeof 가 없어서 아래처럼 지저분한 코딩을 해야한다는점때문에 자바에 실망하실까바 드리는 말인데요.
납득하시기 어렵겠지만 주관적인 제 생각에는 아래처럼 코딩하는경우는 참 드문것 같습니다.
// Byte, Double, Float, Integer, Long, Short
if (testObject instanceof java.lang.Byte) {
// java.lang.Byte.SIZE
} else if (testObject instanceof java.lang.Double) {
// java.lang.Double.SIZE
} else if (testObject instanceof java.lang.Float) {
// java.lang.Float.SIZE
} else if (testObject instanceof java.lang.Integer) {
// java.lang.Integer.SIZE
} else if (testObject instanceof java.lang.Long) {
// java.lang.Long.SIZE
} else if (testObject instanceof java.lang.Short) {
// java.lang.Short.SIZE
} else if {
// 알수없는 타입에 대한 에러 처리
throw new java.lang.RuntimeException("unkown type in ....");
}
그렇게 써 봤는데...
그렇게 써 봤는데, 작동은 됩니다만, 보기가 영 안 좋군요 ㅠㅠ
T는 compile time에 사라집니다.
JAVA generic의 특성상, generic이 method에 붙어 있지 않는 이상 T는 컴파일 타임에 사라집니다.
무슨 뜻이냐면, compile time에 자기 할 일을 다 할 수 잇는
T t;
new ArrayList;
T[] t;
와 같은 문장 이외에
new T();
new T[3];
T.someStaticMethod();
와 같은 문장들은 사용할 수 없습니다.
크게 두 가지 방법이 있는데, 첫번째는 NumberList 생성자를
NumberList(...(기존의 parameter), Class orgclass){
// orgclass 저장
}
와 같이 만들고, exec에서
orgclass.getField("SIZE").getInt(null);
와 같이 실행하면 됩니다.
두 번째는, NumberList라 했으니 저장된 element[i]에 대해
element[i].getClass().getField("SIZE").getInt(element[i]);
와 같이 reflection을 실행하는 것입니다.
답변 감사합니다.
C#을 주로 해왔는데 자바 쓰려하니 많이 서투네요 ㅎㅎ
첨언하자면
이걸 type erasure라고 부르고
이런 이상한(?)게 도입된 이유는 자바 1.5 이전 버전 (정확히 말해 이전 JVM)과의 호환성 때문이었습니다.
(기억이 맞다면) 실제 바이너리 코드상으로는 자바 1.5 이전처럼 (모든 클래스가 Object를 상속하니까) casting 을 합니다.
즉 List l 은 사용되는 곳에서 (String)l 로 casting 됩니다.
그런데 일견 잘못된 선택 같아 보이는 이게 또 웃긴게
Java에서 컴파일 때 casting 되고 class 에 metadata좀 심는것 이외에
사실 JVM 레벨에서 polymorphism 에 대해 뭘 딱히 강제하지 않기 때문에
JVM을 쓰는 다른 언어들이 각각 type에 관해 하고싶은 일을 하는데 수월하다고 하더군요.
댓글 달기