Generics & 'Type Erasure': disingenuous documentation?

cyberion

Junior Member
Sep 7, 2013
1
0
0
Java 5 and onwards allows type variables and parametrized types to be used in declarations. 'Type Erasure' is a grandiose term describing a "process" whereby the compiler eliminates all references to these type variables and parameters in the generated byte code. The reason given is to make Java 5 and onwards compatible with earlier versions of Java, which do not support Generics.

What I suspect is the case is that Generics has been added as incomplete, "design time only" support for parameterized types, which the compiler IGNORES at the point of actual generation of byte code -- hardly what I would call a "process of type erasure". I suspect that the compiler simply does nothing different, and generates the same byte code as the equivalent raw types. The only compiler difference is in its design time validation.

Backward compatibility is a good reason for allowing aliasing of raw types with generic types. It is not a good reason for allowing heap pollution. Heap pollution causes pending runtime exceptions which should be trapped immediately. This suggests that parametrized type information is important at runtime, even when you require backward compatibility.

Can anyone prove me wrong, perhaps by creating a concise example of a generic type that compiles into different byte code from its equivalent raw type?
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
Hmm, not much of a java programmer, but the question confuses me. The idea of generics is that they are generic at the point of declaration. When you "instantiate" a generic type the compiler _should_ generate code that is equivalent to what it would generate for the raw type. Is that not correct?
 

fortioni

Junior Member
Sep 5, 2013
3
0
0
morpher.com
No we can't because the compiler doesn't generate any new code at all; Generics is a compile time thingy; even the runtime casts are still present, even if the compiler 'knows' that a generic type is of a matching concrete type. This is caused by the backwards compatibility b.t.w. Hava a look at the following snippet:

Java Code:
import java.util.ArrayList;
import java.util.List;

public class T {
public static void main(String[] args) {
List<String> list= new ArrayList<String>();

list.add("foo");
System.out.println(list.get(0)+"bar");
}

}
The compiler 'knows' that the list will only contain objects of the type String, but still there's a runtime cast:

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

public static void main(java.lang.String[]);
Code:
0: new #16; //class java/util/ArrayList
3: dup
4: invokespecial #18; //Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: ldc #19; //String foo
11: invokeinterface #21, 2; //InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: getstatic #27; //Field java/lang/System.out:Ljava/io/PrintStream;
20: new #33; //class java/lang/StringBuilder
23: dup
24: aload_1
25: iconst_0
26: invokeinterface #35, 2; //InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
31: checkcast #39; //class java/lang/String
34: invokestatic #41; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
37: invokespecial #45; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
40: ldc #48; //String bar
42: invokevirtual #50; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
45: invokevirtual #54; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
48: invokevirtual #58; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
51: return

}
See line #31; the cast wouldn't be needed if there were no 'raw' types. The only benefit is type safety during compile time and no explicit casts in the source code.
 

fortioni

Junior Member
Sep 5, 2013
3
0
0
morpher.com
Hmm, not much of a java programmer, but the question confuses me. The idea of generics is that they are generic at the point of declaration. When you "instantiate" a generic type the compiler _should_ generate code that is equivalent to what it would generate for the raw type. Is that not correct?
i believe this answers your question ??
 

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
Hmm, not much of a java programmer, but the question confuses me. The idea of generics is that they are generic at the point of declaration. When you "instantiate" a generic type the compiler _should_ generate code that is equivalent to what it would generate for the raw type. Is that not correct?
i believe this answers your question ??

Sarcasm is never appreciated when one is trying to help.


I am in the same boat as Mark but having worked with different types of languages.

String may be able to be manipulated in Java. In other languages the String is a base and is able to be derived from.
The need for the cast is to ensure that the type of String has not been corrupted by inheritance to the point that it can not longer be used as intended.
Another potential is that separate precompiled object could be passed into the array.