1 2 Previous Next 15 Replies Latest reply on Nov 23, 2005 9:13 PM by 843793

    Simple method but hard with generics: compareTo()

    416044
      I adjusted my getMaximum() method to generics to avoid the compiler warnings:
          static public Comparable<Comparable> getMaximum(Comparable<Comparable> comparable1, Comparable<Comparable> comparable2) {
              Comparable<Comparable> result = (comparable1 != null) ? comparable1 : comparable2; //init
              
              if (comparable1 != null && comparable2 != null) {
                  int c = comparable1.compareTo(comparable2);
                  result = (c > 0) ? comparable1 : comparable2; //comparable1 > comparable2?
              }
              
              return result;
          }//getMaximum()
      But now, my other classes that call this method e.g. with 2 dates or with 2 numbers don't compile anymore. I tried
          static public Comparable<? extends Comparable> getMaximum(Comparable<? extends Comparable> comparable1, Comparable<? extends Comparable> comparable2) {
              Comparable<? extends Comparable> result = comparable1; //default
              
              if (comparable1 != null && comparable2 != null) {
                  int c = comparable1.compareTo(comparable2); //compile error
                  if (c <= 0) {
                      result = comparable2;
                  }
              } else if (comparable1 == null) {
                  result = comparable2;
              }
              
              return result;
          }//getMaximum()
      but this code doesn't compile:

      Bound mismatch: The method compareTo(? extends Comparable) of type
      Comparable<? extends Comparable> is not applicable for the arguments
      (Comparable<? extends Comparable>). The wildcard parameter ? extends
      Comparable has no lower bound, and may actually be more restrictive than argument
      Comparable<? extends Comparable>
        • 1. Re: Simple method but hard with generics: compareTo()
          843793
          public class Test {
          
              static public <T extends Comparable<T>> T getMaximum(T comparable1, T comparable2) {
                  T result = (comparable1 != null) ? comparable1 : comparable2;
                  
                  if (comparable1 != null && comparable2 != null) {
                      int c = comparable1.compareTo(comparable2);
                      result = (c > 0) ? comparable1 : comparable2;
                  }
                  
                  return result;
              }
          
              static <T extends Comparable<T>> void test(T t1, T t2) {
               System.out.printf("max(%s, %s) = %s%n", t1, t2, getMaximum(t1,t2));
              }
              public static void main(String... args) {
               test(1, 2);
               test(1.0, 2.0);
               test("aaaa", "bbbb");
              }
          
          }
          You really need to read the generics tutorial:
          http://java.sun.com/j2se/5/pdf/generics-tutorial.pdf
          • 2. Re: Simple method but hard with generics: compareTo()
            416044
            Thanks, I already browsed this tutorial. I just don't understand why the "?" isn't working.
            • 3. Re: Simple method but hard with generics: compareTo()
              416044
              I also tried to translate the 1.4 code of TableSorter.java (code from Java Tutorial) but wasn't able to fix the warning of this code:
                  public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
                      public int compare(Object o1, Object o2) {
                          return ((Comparable) o1).compareTo(o2); //warning
                      }
                  };
              Type safety: The method compareTo(Object) belongs to the raw type Comparable. References to generic type Comparable<T> should be parameterized

              I tried to adjust it with similar code as your suggestion, but without success.
              • 4. Re: Simple method but hard with generics: compareTo()
                843793
                I also tried to translate the 1.4 code of
                TableSorter.java (code from Java Tutorial) but wasn't
                able to fix the warning of this code:
                public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
                public int compare(Object o1, Object o2) {
                return ((Comparable) o1).compareTo(o2); //warning
                }
                };
                There is no way to do that without getting a warning. The
                type system is not expressive enough.
                • 5. Re: Simple method but hard with generics: compareTo()
                  416044
                  Now, that's what I call a default behaviour (show warnings) that wasn't thought through to the end. I guess, most developers want to avoid not only errors but also warnings. And you say, that for this code, it's impossible to resolve this warning?
                  • 6. Re: Simple method but hard with generics: compareTo()
                    843793
                    I also tried to translate the 1.4 code of
                    TableSorter.java (code from Java Tutorial) but wasn't
                    able to fix the warning of this code:
                    public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
                    public int compare(Object o1, Object o2) {
                    return ((Comparable) o1).compareTo(o2);  //warning
                    }
                    };
                    Type safety: The method compareTo(Object) belongs
                    to the raw type Comparable. References to generic
                    type Comparable<T> should be parameterized


                    I tried to adjust it with similar code as your
                    suggestion, but without success.
                    How about this:
                    class Comparables {
                        static <T extends Comparable<T>> Comparator<T> comparatorOfComparables() {
                            return new Comparator<T>() {
                                public int compare( final T first, final T second ) {
                                    return first.compareTo( second );
                                }
                            };
                        }
                    }
                    ??
                    • 7. Re: Simple method but hard with generics: compareTo()
                      843793
                      Now, that's what I call a default behaviour (show
                      warnings) that wasn't thought through to the end.
                      The warnings are thought through to the end. However,
                      we had multiple constraints. An important constraint is
                      compatibility as discussed by Neal Gafter on his blog:

                      http://gafter.blogspot.com/2004/09/puzzling-through-erasure-answer.html

                      Maintaining compatibility means to accept programs that
                      can't be expressed in the new type system. To accomplish this,
                      we give a warning instead of a error.

                      But sometimes it is just impossible to make your pre-generics
                      code generic because you can't redesign your entire application
                      with generics in mind. So you will be able to suppress unchecked
                      warnings on per-method basis. Use the @SuppressWarnings("unchecked")
                      annotation. Currently, the compiler will simply ignore it, but
                      that will change in future versions.
                      • 8. Re: Simple method but hard with generics: compareTo()
                        416044
                        How can we use this @SuppressWarnings("unchecked")? I didn't found an answer in this forum or in the Annotations doc (http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html).
                        • 9. Re: Simple method but hard with generics: compareTo()
                          416044
                          I found an article "What is the SuppressWarnings annotation?" (http://www.langer.camelot.de/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20the%20SuppressWarnings%20annotation?) on the internet, so I added
                          @SuppressWarnings("unchecked")
                          public class TableSorter extends AbstractTableModel { ...
                          but I still get the warnings:

                          [javac] Note: Some input files use unchecked or unsafe operations.
                          [javac] Note: Recompile with -Xlint:unchecked for details.

                          I also tried this:
                          @SuppressWarnings(value={"unchecked","unsafe"})
                          public class TableSorter extends AbstractTableModel {...
                          with no success. (Note: this TableSorter class is the only class with unchecked warnings, so there are no other classes that can cause these warnings.)
                          • 10. Re: Simple method but hard with generics: compareTo()
                            843793
                            Go back and read the last sentence of what Peter said more carefully.
                            • 11. Re: Simple method but hard with generics: compareTo()
                              416044
                              Why mentioning this if it doesn't work? It doesn't help me now if it is planned to be supported in the future.

                              After all I've read so far:

                              - you can't convert all your 1.4 code to genercis code, with the result of having warnings left
                              - you can't suppress the warnings because @SuppressWarnings("unchecked") is not implemented so far (=> still warnings)
                              - note the -nowarn/-Xlint:none javac parameter ... but then you also get no other warnings

                              => with 1.5, you have to live with warnings because you can't resolve them (except projects that don't have such cases). This leads to the effect that you get used to the warning message after compilation that itself leads to the developer to tend to ignore compiler warnings. I wonder if i'm the only one who is not happy with this ...?
                              • 12. Re: Simple method but hard with generics: compareTo()
                                843793
                                Whilst I know this thread is quite old, I found it whilst trying to solve the same problem.

                                For reference, the following code can be used to overcome the 1.5 compiler warning for the COMPARABLE_COMAPRATOR function in Sun's TableSorter.java.
                                  
                                public static final Comparator<Object> COMPARABLE_COMAPRATOR = new Comparator<Object>()
                                  {
                                    public int compare(Object o1, Object o2)
                                    {
                                      int retval = -1;
                                      Class o1class = o1.getClass();
                                      Class o2class = o2.getClass();
                                      if (o1class.equals(o2class))
                                      {
                                        try
                                        {
                                          Method method = o1class.getDeclaredMethod("compareTo", new Class[]
                                                                                    {o2class});
                                          try
                                          {
                                            Integer answer = (Integer) method.invoke(o1, o2);
                                            retval = answer.intValue();
                                          }
                                          catch (Exception e)
                                          {
                                            System.out.println("Call to method failed.");
                                          }
                                        }
                                        catch (NoSuchMethodException e)
                                        {
                                          System.out.println("No compareTo() method.");
                                        }
                                      }
                                      return retval;
                                    }
                                  };
                                Hope this helps someone.

                                Regards,
                                Ray
                                • 13. Re: Simple method but hard with generics: compareTo()
                                  843793
                                  How about this for TableSorter:
                                      public static final Comparator<Comparable<Comparable>> COMPARABLE_COMAPRATOR = new Comparator<Comparable<Comparable>>() 
                                      {
                                          public int compare(Comparable<Comparable> arg0, Comparable<Comparable> arg1) 
                                          {
                                              return arg0.compareTo(arg1);
                                          }
                                      };
                                  • 14. Re: Simple method but hard with generics: compareTo()
                                    843793
                                    How about this for TableSorter:
                                    public static final
                                    inal Comparator<Comparable<Comparable>>
                                    COMPARABLE_COMAPRATOR = new
                                    Comparator<Comparable<Comparable>>() 
                                    {
                                    public int compare(Comparable<Comparable>
                                    parable> arg0, Comparable<Comparable> arg1) 
                                    {
                                    return arg0.compareTo(arg1);
                                    }
                                    };
                                    Doesn't know what to make of
                                    Comparator<Comparable><Comparable>>
                                    R
                                    1 2 Previous Next