aspose file tools*
The moose likes Java in General and the fly likes Inferring type in call to generic method: how does it work? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Inferring type in call to generic method: how does it work?" Watch "Inferring type in call to generic method: how does it work?" New topic
Author

Inferring type in call to generic method: how does it work?

Anand Kane
Greenhorn

Joined: Mar 15, 2005
Posts: 10
Given below is the code that threw me into confusion; line # 30 in particular. Since both the generic parameters being passed to method 'add' are of type Shape, I assumed that for this call to method 'add', the generic type would be inferred to 'Shape'. But since it doesn't generate a class cast exception at line# 30, it is obvious that generic type is inferred as 'Object' and not Shape.

Could someone please explain the way generic types are inferred when a generic method is called?

Thanks


Greg Charles
Sheriff

Joined: Oct 01, 2001
Posts: 2771
    
  10

Actually, that was sort of surprising to me too, but I guess it makes sense given how Java implements generics. Generics are a late addition to the Java language and could be called a bit of a kludge in the sense that they only serve as hints to the compiler, and don't affect the resulting byte code. That is, although the basic Collection class became Collection<T> when generics were introduced, the byte codes for the two are the same. That's good because it allows older Java applications to run without modification on newer JVMs, but has some drawbacks too.

If you declare a collection to contain type ... Shape, for example ... the compiler will tell you if you try to add a non-Shape to it, and won't make you cast elements you retrieve to Shape. That's good and it saves a lot of tedious coding. However, if you try to cast a random object to type T, like this example, you won't see an error, because the runtime doesn't know what T is. It considers it to be Object, unless you specifically make T extend some other class. That exposes some weakness in Java's implementation of generics, but fortunately, it takes a fairly contrived example to do it.
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

I don't really see the problem. The compiler is kind enough to warn us that we're using unchecked operations. And because we ignore it we get punched in the face with an ClassCastException when we try to use it.

If you don't know what caused this then read about type erasure.
Small example:


"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --- Martin Fowler
Please correct my English.
John Louis
Greenhorn

Joined: Aug 14, 2008
Posts: 10
Dear Ranchers,
Everyone seems to stick with the fact that type info in generics is lost after compilation and that at runtime its just the generic type specified to the left of the "<" that finally matters. If so, how does the following program work?



Output is: hithere and 3 as expected. How does it delegate the call to the correct method at runtime?

Regards John.

PS:- In helios, this file is not compiling. Is there a workaround for that?
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3378
    
    9
It doesn't. Java always decides which methods to use at compile time. The method calls are hardcoded into the program. Example:
This will print "I got an object!"
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

Because at compile time it is know which method to call.
John Louis
Greenhorn

Joined: Aug 14, 2008
Posts: 10
Stephan van Hulst wrote:It doesn't. Java always decides which methods to use at compile time. The method calls are hardcoded into the program. Example:
This will print "I got an object!"


Thanks Stephen. Do you have any idea why it doesn't get compiled in helios?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19543
    
  16

What's the error you get? Is it perhaps the varargs on line 16?


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
John Louis
Greenhorn

Joined: Aug 14, 2008
Posts: 10
Rob Spoor wrote:What's the error you get? Is it perhaps the varargs on line 16?


Hi Rob,
The error says:
"Method add(Collection<Integer>) has the same erasure add(Collection<E>) as another method"
and
"Method add(Collection<String>) has the same erasure add(Collection<E>) as another method"
against the 2 method definitions.
In an earlier version of eclipse, its getting compiled successfully, though I have now forgotten which version that was now.

Regards
John
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3378
    
    9
It's because the Java Language Specification (ยง8.4.2) says it's actually illegal.

The fact that the method to be used *can* be derived, doesn't mean it's legal. Helios has it right. Older versions do not give a compile error, while they should.
Vijitha Kumara
Bartender

Joined: Mar 24, 2008
Posts: 3775

Helios has it right. Older versions do not give a compile error, while they should...

Not sure what the verison of JDK used by the Helios here (Or it may have added some constraints which are not enforced by the JDK even the JLS say so) ...
I don't get an error on JDK 1.6.0_07 (no IDE), have to check on another version and in the IDE too...


SCJP 5 | SCWCD 5
[How to ask questions] [Twitter]
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19543
    
  16

Because of type erasure, the methods get turned into "public int add(Collection)" and "public String add(Collection)". As you see both methods now have the same name and parameter list. Every compiler should fail compilation. If one doesn't then that compiler is actually broken.
Vijitha Kumara
Bartender

Joined: Mar 24, 2008
Posts: 3775

Rob Spoor wrote:...Every compiler should fail compilation. If one doesn't then that compiler is actually broken.

Theoretically Yes, but the interesting thing is even 1.6.0_21 and 1.6.0_23 (both 64 bit) don't complain in this particular scenario...
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19543
    
  16

Apparently so. I never even knew my current compiler allows this.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Inferring type in call to generic method: how does it work?
 
Similar Threads
Generics Doubt.
Generics Question
How to Use Comparator or BeanPropertyUtil to sort by multiple criteria
Simple J2SE 5.0 Tiger Notes
Inferring the correct type parameter