• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

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

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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


 
Sheriff
Posts: 3064
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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:
 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Saloon Keeper
Posts: 15727
368
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Bartender
Posts: 2700
IntelliJ IDE Opera
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because at compile time it is know which method to call.
 
John Louis
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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?
 
Sheriff
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What's the error you get? Is it perhaps the varargs on line 16?
 
John Louis
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Saloon Keeper
Posts: 15727
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Bartender
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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...
 
Rob Spoor
Sheriff
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 22815
132
Eclipse IDE Spring Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Apparently so. I never even knew my current compiler allows this.
 
He's my best friend. Not yours. Mine. You can have this tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic