자바에서 제네릭 쓸 때...

hiluciano의 이미지

public final class NumberList<T extends Number>
{
void exec()
{
//int size = sizeof(T); // 이런 부분... 꼭 T의 크기를 구할 필요가 있을 때...
}
}

C++의 sizeof처럼 자바에서도 제네릭 형식의 크기를 구할 수 있는 방법이 없을까요?

emptynote의 이미지

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 ....");
}

hiluciano의 이미지

그렇게 써 봤는데, 작동은 됩니다만, 보기가 영 안 좋군요 ㅠㅠ

익명 사용자의 이미지

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을 실행하는 것입니다.

hiluciano의 이미지

C#을 주로 해왔는데 자바 쓰려하니 많이 서투네요 ㅎㅎ

sblade의 이미지

이걸 type erasure라고 부르고
이런 이상한(?)게 도입된 이유는 자바 1.5 이전 버전 (정확히 말해 이전 JVM)과의 호환성 때문이었습니다.

(기억이 맞다면) 실제 바이너리 코드상으로는 자바 1.5 이전처럼 (모든 클래스가 Object를 상속하니까) casting 을 합니다.
즉 List l 은 사용되는 곳에서 (String)l 로 casting 됩니다.

그런데 일견 잘못된 선택 같아 보이는 이게 또 웃긴게
Java에서 컴파일 때 casting 되고 class 에 metadata좀 심는것 이외에
사실 JVM 레벨에서 polymorphism 에 대해 뭘 딱히 강제하지 않기 때문에
JVM을 쓰는 다른 언어들이 각각 type에 관해 하고싶은 일을 하는데 수월하다고 하더군요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.