• Post Reply Bookmark Topic Watch Topic
  • New Topic

Comparable and Generics  RSS feed

 
Gytis Jakutonis
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I want to implement some operations like 'more', 'less', 'equal'. For 'more' and 'less' I want to use Comparable api. So in general operations may look like this:


But the problem is that with 1.5 jdk I get unchecked call wraning for compareTo(). Is there any elegant way to solve this issue? Thanks in advance.
 
Mogens Nidding
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Gytis!

Good question. After reading your question, I downloaded JDK 1.5.0 to try out your example and generics for the first time. By peeking a bit at chapter 9 of Gilid Bracha's excellent Generics tutorial, I found this to be the "correct" way to get rid of the unchecked warning:



Now, doit takes a list of objects of type T. T can be any type that is comparable to any supertype of T (including T itself). For instance (this is admittedly a bit far fetched, but it has to be), T could be GregorianCalender, which is comparable to Calendars in general.

I must say the generified solution is a little verbose when compared to a single cast in this case.

Hope it makes sense. Good luck in your future generic adventures :-)
 
Gytis Jakutonis
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Nicky,
thanks for your replay. I have two more questions about the code you have posted:
  • why can't we use just <T extends Comparable<T>>
  • your solution is restricted to Comparable types only, but some operations like EQUALS or IS_NULL does not need Comparable arguments at all


  • thanks in advance,
    Gytis
     
    Mogens Nidding
    Ranch Hand
    Posts: 77
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Gytis: why can't we use just <T extends Comparable<T>>

    <T extends Comparable<T>> almost, but not entirely does the job. It is best explained with an example, such as GregorianCalendar from before. If you insert GregorianCalendar instead of T, you get

    <GregorianCalendar extends Comparable<GregorianCalendar>>

    which is not true! Therefore, a list of GregorianCalendars could not be used as input to doit if we just used <T extends Comparable<T>>.
    GregorianCalendar does implement Comparable<Calendar>,
    but it does not implement Comparable<GregorianCalendar>!
    I admit this is not very intuitive, but it's the way generics work in general, and it is the reason wildcards were introduced.

    I have an idea of how to extend the language so that we won't necessarily have to write <T extends Comparable<? super T>> every single time, but that's another I discussion I may post somewhere else if I suddenly have oodles of time.

    Gytis: your solution is restricted to Comparable types only, but some operations like EQUALS or IS_NULL does not need Comparable arguments at all

    True, and I didn't even think about that. It just makes your question even better . I'm not sure there is any super elegant solution to this problem. If your client does this...



    then the original code you posted (with the cast) will throw a ClassCastException if myOp == MORE because Number does not implement Comparable! This is exactly the reason the compiler emits an unchecked warning with JDK1.5: In some situations, the code will fail.

    If you know for sure that no client is going to do something like that, and you just want to cast without triggering a warning (perhaps this is what you asked for from the very beginning?), I am going to have to owe you a reply, since I didn't dig into it any deeper and don't have too much time right now. Try searching for @SuppressWarnings("unchecked"), it might give you a solution, although not the elegant one you were hoping for. I think (hope) there is be a better solution.

    Please let me know if you make any more experiences in this matter, as I find it very interesting: Perhaps generics didn't entirely get rid of the need for casting anyway! I will also look into it some more later, but for the moment, my lunch break is over :-)
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!