Win a copy of OCP Java SE 8 Programmer II Exam Study Guide this week in the OCP forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Type erasure question  RSS feed

 
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>?
 
author
Marshal
Posts: 23439
138
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
 
Marshal
Posts: 58421
178
  • 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
Marshal
Posts: 23439
138
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
 
Saloon Keeper
Posts: 8618
161
  • 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: 58421
178
  • 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: 8618
161
  • 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.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!