Generics inside byte code ?

After “Can I delude generics ?“, I’ve tried to delude javac with failure.

If you compile a method which has Generics inside its prototype like :

public class L {
    public void doSomething(List<String> l) {
        l.add("str");
    }
}

and after you uncompile it with jad you’ll get :

public class L {
    public void doSomething(List l) {
        l.add("str");
    }
}

Ohoho ! Generic has disappeared oO.
Hum … reality is that generics don’t exist in bytecode ? And now can I use this class with List<Integer> ?
Hum try this (after having deleted L.java) :

public class M {
    public static void main(String[] argv) {
        new L().doSomething(new ArrayList<String>());
    }
}

And you’ll get a compilation failure …

M.java:6: doSomething(java.util.List<java.lang.String>) in L cannot be applied to (java.util.ArrayList<java.lang.Integer>)
		new L().doSomething(new ArrayList<Integer>());
		       ^
1 error

I suppose that in fact generic type is inside bytecode, but jad is maybe a little blind …
and with javap ?

javap -c L :

Compiled from "L.java"
public class L extends java.lang.Object{
public L();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>":()V
   4:	return

public void doSomething(java.util.List);
  Code:
   0:	return

}

Object too …

Now try “hexdump -C L.class :

00000000  ca fe ba be 00 00 00 32  00 11 0a 00 03 00 0e 07  |ÊþºŸ...2........|
00000010  00 0f 07 00 10 01 00 06  3c 69 6e 69 74 3e 01 00  |........<init>..|
00000020  03 28 29 56 01 00 04 43  6f 64 65 01 00 0f 4c 69  |.()V...Code...Li|
00000030  6e 65 4e 75 6d 62 65 72  54 61 62 6c 65 01 00 0b  |neNumberTable...|
00000040  64 6f 53 6f 6d 65 74 68  69 6e 67 01 00 13 28 4c  |doSomething...(L|
00000050  6a 61 76 61 2f 75 74 69  6c 2f 4c 69 73 74 3b 29  |java/util/List;)|
00000060  56 01 00 09 53 69 67 6e  61 74 75 72 65 01 00 27  |V...Signature..'|
00000070  28 4c 6a 61 76 61 2f 75  74 69 6c 2f 4c 69 73 74  |(Ljava/util/List|
00000080  3c 4c 6a 61 76 61 2f 6c  61 6e 67 2f 53 74 72 69  |<Ljava/lang/Stri|
00000090  6e 67 3b 3e 3b 29 56 01  00 0a 53 6f 75 72 63 65  |ng;>;)V...Source|
000000a0  46 69 6c 65 01 00 06 4c  2e 6a 61 76 61 0c 00 04  |File...L.java...|
000000b0  00 05 01 00 01 4c 01 00  10 6a 61 76 61 2f 6c 61  |.....L...java/la|
000000c0  6e 67 2f 4f 62 6a 65 63  74 00 21 00 02 00 03 00  |ng/Object.!.....|
000000d0  00 00 00 00 02 00 01 00  04 00 05 00 01 00 06 00  |................|
000000e0  00 00 1d 00 01 00 01 00  00 00 05 2a b7 00 01 b1  |...........*·..±|
000000f0  00 00 00 01 00 07 00 00  00 06 00 01 00 00 00 03  |................|
00000100  00 01 00 08 00 09 00 02  00 06 00 00 00 19 00 00  |................|
00000110  00 02 00 00 00 01 b1 00  00 00 01 00 07 00 00 00  |......±.........|
00000120  06 00 01 00 00 00 05 00  0a 00 00 00 02 00 0b 00  |................|
00000130  01 00 0c 00 00 00 02 00  0d                       |.........|
00000139

Yeah ! generic is here, inside the right column 😉

Bytecode contains the original generic type, and uses it to check at compile time.

But is it the same at the runtime ? We’ll verify this later 😉

Advertisements

2 thoughts on “Generics inside byte code ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s