Help coderanch get a
new server
by contributing to the fundraiser
  • 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
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Carey Brown
  • Mikalai Zaikin
Bartenders:
  • Lou Hamers
  • Piet Souris
  • Frits Walraven

Generics Methods

 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone



why does Object x = t.findLarger(123, “456”); work??

I mean 123 and "456" are of different types? How can these be compared in the line x.compareTo(y)??


 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It works because both Integer and String implement Comparable. So it can compile that line, interpreting T = Comparable. The thing is, Comparable is a generic class as well, and for complete use of generics (which would prevent you comparing different types like that) you need to do something like this:
Then t.findLarger(123, "456") won't compile because Integer implements Comparable<Integer>, and String implements Comparable<String>, so it can't find a single value of T to match them both.
 
Anshul Singhal
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Mathew,
Thanks for replying. But I still don't get in the former case where it was <T extends Comparable>, You interpreted it as T= Comparable and in your case where <T extends Comparable<? super T>> we are unable to compile.

If possible can you please explain the flow of it.
 
Saloon Keeper
Posts: 15704
367
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because your original code is not type-safe. I haven't run it, but I'm pretty sure it would throw a ClassCastException when you tried finding the larger of an Integer and a String.

You are using a raw type. Comparable is a generic interface, and you're using its raw form. The compiler will actually warn you about this. Instead, you need to parameterize Comparable, so the compiler will tell you you're doing something wrong when you're trying to compare an Integer to a String.

You could do something like public <T extends Comparable<T>> T findLarger(T x, T y) to resolve this issue, but this has a big limitation. You can only compare types that directly implement Comparable, but not their subclasses.

For instance, let's say you have a class Fruit implements Comparable<Fruit>. If Fruit has a subclass Apple, then you can not use your method to compare two apples, because an Apple is not a Comparable<Apple>, it's a Comparable<Fruit>.

So instead of using <T extends Comparable<T>>, we use <T extends Comparable<? super T>>, so we can also use it to get the larger of two apples.

Using this declaration will make sure that the method works as intended, but at the same time compilation will fail if you try to compare incompatible types. Perfect!
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'll try. In the first case:
You can call this with any arguments where you can pick a T that fits them all.

Now, if you call t.findLarger(123, "456"), what can T be? The first argument is an int, which will be boxed to an Integer. So T can be Integer, or any supertype of Integer. Which means Number, Object, Serializable and Comparable (implemented interfaces are possible supertypes as well). But there's a constraint: T extends Comparable. That rules out Number, Object and Serializable. T must be either Integer or Comparable.

Now consider the second argument. It's a String. That would match T being String, Object, Serializable, Comparable or CharSequence. Again, the constraint rules out some of them, so T can be String or Comparable.

The line will compile if we can pick a T that matches both arguments. We can: T = Comparable.

As you've already realised, that lets you do things that don't make sense, like comparing an integer and a string. But, Comparable is actually a generic interface, and if we give it a generic type we can make the compile-time checking stronger. So we can try:
Now if we try and call t.findLarger(123, "456"), what can T be?

Looking at the first argument, and considering the constraint, T can be Integer, or Comparable<Integer> (which is implemented by Integer). Looking at the second argument, T can be String or Comparable<String>. Which means that there's no choice of T that matches both arguments. So the compiler will disallow it.

The version I gave before:
is actually a more flexible version that does the same thing. Since Integer implements Comparable<Integer>, and String implements Comparable<String> you don't need this more flexible version. But an example where you would is the class java.sql.Date (used with databases). This extends java.util.Date, and implements Comparable<java.util.Date>. So a java.sql.Date argument could never be used with a constraint like T extends Comparable<T>, but it could be used with T extends Comparable<? super T>. This last bit is a bit complicated, though, so don't worry too much if it doesn't make sense at the moment. Just try and understand the difference between the first two examples.

Does that help?
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic