File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes Generics doubt Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Generics doubt" Watch "Generics doubt" New topic
Author

Generics doubt

Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231


Can anybody tell me when is the actual type of <T> determined by the compiler for the method meth()?
If it is at LINE#1 then as per my understanding the cast at LINE#2 in method meth() from Float to Byte should fail as Byte IS-NOT-A Float because the cast to type (T) would already have been resolved at compile time and thus this should generate a compile time error?
But the code compiles and happily prints the output.
What am i missing here?


thanks
Harvinder
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24184
    
  34

You're assuming that there's runtime type checking of the contents of the list itself, but that's simply not true. Generics work by erasure, which means (in essence) that the compiler enforces certain type restrictions, but at runtime, the types have been erased; the List itself works only with Object references. You're tricking the compiler by using that type wildcard. If you tried to take that Float out of the list from within main, the compiler will have inserted a cast to String, and you'd get a runtime exception at that point.


[Jess in Action][AskingGoodQuestions]
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

With method-local generics, the method call determines the actual type. For instance, Collections.emptySet() returns a Set<String> if the reference type the value is assigned to is Set<String>. In your example, it is LINE#1 that determines that T is Byte.

As EFH said, during runtime there is no more T so the cast is basically (Object). Because your example can cause problems the compiler warns you - casting to T is highly discouraged, and your example shows exactly why. That's a ClassCastException waiting to happen once you retrieve the Float object but assign it to a Byte reference.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
Sorry guys for posting a bit late. I was on a vacation
Thanks for your answers. i have a doubt.

Originally posted by Ernest-Friedman Hill:

If you tried to take that Float out of the list from within main, the compiler will have inserted a cast to String, and you'd get a runtime exception at that point.


The cast would not be a String but to a Byte as the list1 is a List of Bytes. Isn't it?

Suppose if i change the invocation on LINE#1 as
new Test().meth(list);// LINE#1
then what would be the generic type T resolved to? Is it Object ? I guess not because it is only Number which satisfies the construct <T extends Number> so it should be Number
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9302
    
  17

Taking the original code as base let me explain it to you.

Harvinder since the type of meth T is not used in the method except for the return type, so there are two ways that the type of T can be decided by the compiler.

1. By examining the type in which the return value is being catched. So if you write this

List<Byte> = new Test().meth(null);

then the compiler will know that the type of T is Byte. The other way is to use this syntax

new Test().<Byte>meth(null);

Now here too the compiler will be able find that the type of T is Byte.

But if you don't provide any information to the method, then the type of T will become Number as the declaration of meth defines <T extends Number>...


SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
o.k. that implies if I change <T extends Number> to <T> then the generic Type T would be resolved to an Object.
Moreover, the argument to meth(List<?> type) can accept a List of objects of any type. This makes it inappropriate to use in combination with generic type declaration of <T extends Number> as adding anything to a collection of generic type T declared within the method meth() can result in type unsafe addition as LINE#1 in original code shows.
Thanks guys for chipping in.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Generics doubt