• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Question about generic methods

 
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


This code prints "f(Object) called"

In my thoughts the generic type T in method g will be typed to String. But it invokes the method f with an Object argument.
Does this happen because of type erasure? Can someone explain?
 
Marshal
Posts: 79177
377
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Moving to different forum; this isn't a beginning” question.

Let's copy'n'paste your code and compile it:-You will see from line 37 that, like all method name overloading, the path of execution is resolved at compile time. The method cannot predict what type will be used as an argument to it. You might have called it with a Strin‍g as its argument, but other code might call it with a Foo or a List<BigInteger> or any of the millions of other types known. The compiler must therefore be able to call that method with any type, and only Object will fit the bill. You can get that method  to compile by changing it to ...<T extends Integer>..., but since Integer is a final class, that is a totally pointless change.
 
Saloon Keeper
Posts: 15510
363
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It wouldn't call the overload that takes a String, even if Java didn't use type erasure. Type erasure affects what the application can do at run time. Method overload resolution is not done at run time, but at compile time.

When a statement contains a method invocation, the compiler determines what method overload is used before the application is run. That means that the compiler must determine which overload of f() to call from g(), without knowing the actual runtime type of T, so it can only use type bounds on T in its determination.

Since T has no explicit type bounds, the upper type bound on T is Object, so the overload that accepts Object is called.

Try the following:

Now that T has an upper bound of String, the compiler will call the overload that accepts String.
 
Author
Posts: 285
12
Scala IntelliJ IDE Netbeans IDE Python Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another way to think of/phrase this is that Java, like most OO languages (but not, I think smalltalk), exhibits dynamic invocation based on the type of the prefix parameter, but NOT the argument types. Arguments, as Stephan says, are only used for compile time polymorphism (which is so limited that a lot of OO folks don't even use the term polymorphism to describe it, even though much of the formal literature does).
 
reply
    Bookmark Topic Watch Topic
  • New Topic