Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2006

Tip: Looking for answers? Try searching our database.

Generics Question

Thread view: 
Rhino - 10 Mar 2006 00:52 GMT
I am getting this warning:

   Type safety: The method compareTo(Object) belongs to the raw type
Comparable.

   References to generic type Comparable<T> should be parameterized

in the following code but I'm not sure how to rewrite the code so that the
error goes away (I don't want to disable the warning in the compiler). The
'//<===' comment indicates exactly where the warning occurs:

=================================================================

public class SimpleRange {

   public static int NUMBER_OF_ELEMENTS = 2;

   Comparable lowValue = null;
   Comparable highValue = null;

   public SimpleRange(Comparable firstObject, Comparable secondObject) {

       if (firstObject == null) {
           throw new IllegalArgumentException("The first Object cannot be
null.");
       }

       if (secondObject == null) {
           throw new IllegalArgumentException("The second Object cannot be
null.");
       }

       /*
        * Since only Comparable objects are permitted by this constructor,
compare them
        * and store the lower one in the lowValue class variable. Store the
other one in the
        * highValue class variable.
        */
       try {
           if (firstObject.compareTo(secondObject) > 0) { //<=== Warning
occurs here
               this.highValue = firstObject;
               this.lowValue = secondObject;
           } else {
               this.lowValue = firstObject;
               this.highValue = secondObject;
           }
       } catch (ClassCastException cc_excp) {
           throw new IllegalArgumentException("The first Object, " +
firstObject.toString() + ", belongs to class " +
firstObject.getClass().getName() + ". The second Object, " +
secondObject.toString() + ", belongs to class " +
secondObject.getClass().getName() + ". Both Objects implement the Comparable
interface but they cannot be compared with each other.");
       }

   }
}

=================================================================

How do I revise my code to prevent this warning?

I revised the method signature to say:

   public SimpleRange(Comparable<Object> firstObject, Comparable<Object>
secondObject)

and this stopped the warning but then I wasn't sure how to invoke the
constructor; old invocations like:

   SimpleRange myRange = new SimpleRange("cat", "dog");

stopped working when I did that.

I'm afraid I don't follow generics entirely yet....

Signature

Rhino

John C. Bollinger - 10 Mar 2006 05:06 GMT
> I am getting this warning:
>
[quoted text clipped - 73 lines]
>
> I'm afraid I don't follow generics entirely yet....

It's hard to dabble in generics unless you're willing to put up with (or
turn off) the warnings.  You very quickly run into situations where you
need to perform a generics overhaul on classes, class hierarchies, and
even whole applications in order to get everything right with respect to
generics.  That's not intended to be critical of generics, by the way;
generics constitute a significant and fundamental change to Java's type
system, so its not surprising that it their use has broad impact.

On to the problem at hand.  You have run into one of those situations
that is not neatly restricted to a single method.  As is often the case,
you have a larger-scale design problem that generics can solve, but for
which your current code appears to follow the best model available in
1.4.  The issue revolves around your model of a "range".  You have
designed a generic range by defining bounds with use of a very abstract
type (Comparable), which is good pre-1.5 style, but the /declarations/
do not express the constraint that the bounds be comparable to each
other.  More succinctly, the question that the compiler wants to be able
to answer is "SimpleRange of /what/?"  This demands a full generic
treatment, something along these lines:

public class SimpleRange<T extends Comparable<? super T>> {

    T lowValue;
    T highValue;

    public SimpleRange(T low, T high) {
        if (low == null) {
            throw new IllegalArgumentException("Null lower bound");
        } else if (high == null) {
            throw new IllegalArgumentException("Null upper bound");
        } else {
            lowValue = low;
            highValue = high;

            // No need to test mutual comparability
        }
    }

    // other methods ...
}

Key points:
(1) The class is made generic, with one type parameter (T) defining the
type of the range's bounds, and presumably also the type of the members
of the range.
(2) The type parameter is assigned an upper bound (Comparable<? super
T>) that ensures that valid type arguments are all of types that are
comparable to themselves, whether by implementing Comparable directly or
by inheriting it from a superclass.
(3) The type parameter allows easy expression of the constraint that the
constructor arguments be of mutually compatible, Comparable, types.
(4) Making this change will produce a cascade of type safety warnings
from the compiler, requiring you to specify a type argument everywhere
you declare a reference of this type.

Signature

John Bollinger
jobollin@indiana.edu

Thomas Hawtin - 10 Mar 2006 19:29 GMT
> (4) Making this change will produce a cascade of type safety warnings
> from the compiler, requiring you to specify a type argument everywhere
> you declare a reference of this type.

The amount of explicit type arguments can be reduced by using a creation
method rather than the constructor directly. Methods, unlike types, need
not have their generic type arguments specified explicitly.

    public static <
        T extends Comparable<? super T>
    > SimpleRange<T> create(T low, T high) {
        return new SimpleRange<T>(low, high);
    }

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

John C. Bollinger - 12 Mar 2006 05:24 GMT
>> (4) Making this change will produce a cascade of type safety warnings
>> from the compiler, requiring you to specify a type argument everywhere
[quoted text clipped - 9 lines]
>         return new SimpleRange<T>(low, high);
>     }

A good and valid point, but it doesn't really solve the problem that the
 code of the class's clients is going to need to be modified all over
the place.  In particular, it is going to need to be modified everywhere
an instance is created, whether to insert the correct type argument or
to switch from obtaining an instance via "new" to obtaining one via a
factory method.  Also, I was more talking about parameterizing
/declarations/ than about parameterizing constructor invocations, and
none of that would be affected by your suggestion.

Signature

John Bollinger
jobollin@indiana.edu

Roedy Green - 10 Mar 2006 22:07 GMT
On Thu, 9 Mar 2006 19:52:29 -0500, "Rhino"
<no.offline.contact.please@nospam.com> wrote, quoted or indirectly
quoted someone who said :

>Comparable firstObject

Look at the code for Comparable and you will see:
public interface Comparable<T>

That is your clue. Wherever you have said Comparable you must say
Comparable<T> or Comparable<String> or the like.

For notes on implementing Comparable with generics see
http://mindprod.com/jgloss/comparable.html

see http://mindprod.com/jgloss/generics.html for the hair splitting.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.