• Post Reply Bookmark Topic Watch Topic
  • New Topic

Type erasure question  RSS feed

 
Edwardd Lee
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

The output of the code above is:

If type erasure replaces T with Object at runtime, why doesn't getClass( ) return class java.lang.Object instead for a String? Is there a difference between how type erasure works for T and SomeClass<T>?
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Edwardd Lee wrote:
If type erasure replaces T with Object at runtime, why doesn't getClass( ) return class java.lang.Object instead for a String? Is there a difference between how type erasure works for T and SomeClass<T>?


Type erasure refers to the references in the generated code -- in that the generics are erased and replaced (in most cases) with Object references. This is done for backward compatibility reasons. The actual instances at runtime do not get affected.

Henry
 
Campbell Ritchie
Marshal
Posts: 56522
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Edwardd Lee wrote:. . . why doesn't getClass( ) return class java.lang.Object instead for a String? . . .
[Another answer.]
Because getClass() is an instance method, and as such it is polymorphic. Although the method itself is final cannot be overridden, the value returned depends on the runtime type of the object, not its declared type. You can read about that here. The result from getClass is the Class object corresponding to the class the object was created from.
Before generics, we had to do things like this:-Output:-
java.lang.String
java.lang.Integer
 
Edwardd Lee
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the responses! Why, then, does test.printList(new ArrayList<String>()); returns class java.util.ArrayList, but not something like class java.util.ArrayList<String>?

Also, if actual instances at runtime does not get affected, why can we not initiate a type variable (such as new T[])?
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Edwardd Lee wrote:Why, then, does test.printList(new ArrayList<String>()); returns class java.util.ArrayList, but not something like class java.util.ArrayList<String>?


The getName() method of the reflection library simply doesn't return the generic portion. If you want that, I believe that there is a getTypeParameters() method that you can use.... but ... to be honest, I have never used reflection for generics, so I can't help more than that.

Edwardd Lee wrote:
Also, if actual instances at runtime does not get affected, why can we not initiate a type variable (such as new T[])?


Not sure what to tell you here. The type of the instance doesn't change, during the erasure of the generic -- meaning it is still an ArrayList instance. If you want to argue that the type has changed, because the generic has been removed, then .... okay ... I guess it is a valid argument that the type has changed.

It is a subtle point, so, I am not sure what are you trying to say?  Are you saying that since type erasure affects the instance, then it must change the type of the instance, and the reflection libraries are wrong?

Henry
 
Stephan van Hulst
Saloon Keeper
Posts: 7963
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can not do new T[size], because it needs to allocate a chunk of memory of a size that depends on the actual type of T, and you don't know the actual type of T.

It would be possible to do this if the actual type of T was known at runtime, but it isn't, because of type erasure.
 
Campbell Ritchie
Marshal
Posts: 56522
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But oddly enough, you can cast such an array to (T[]).
 
Stephan van Hulst
Saloon Keeper
Posts: 7963
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually I was mistaken in my previous post. The size of the elements is always known ahead of time: It's the size of a pointer.
 
Edwardd Lee
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:It is a subtle point, so, I am not sure what are you trying to say?

Sorry I actually made a typo. I meant to type T() instead of T[] (though it doesn't make much difference to the question since in both cases instance(s) of T are created.)
Reading through the answers I gain some understandings are hopefully correct.

The reason why line 1 works is that although K is referenced as Object at runtime, the actual type of k1 doesn't change, so line 1 will accurately return its actual class supplied at runtime.
The reason why line 2 won't compile is that since K is referenced as Object at runtime, this line will essentially be like Object k2 = new K();, which is of little use to users, therefore Java doesn't allow this initialization altogether.
Is my understanding correct?
 
Edwardd Lee
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
this line will essentially be like Object k2 = new K();

Oops in the reply above I meant to type: Object k2= new Object();
What's with all the typos by me today haha.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!