Correctly Assigning Variables of a Generic Type

62 views Asked by At

I would like to correctly set the types for the Comparable objects. I have the following method:

abstract <T> boolean check( Comparable<T> first, T second );

For now, the parameters first and second are declared as follows:

 Comparable first = convertStringValueToType(attribute.getValue(), attribute.getType());
 Comparable second = convertStringValueToType(expectedValue.getFirst(), attribute.getType());

The method convertStringValueToType() returns either a String, BigDecimal, or Boolean. Unfortunately I cannot just use attribute.getType() as that returns another object (DataElementAttributeType).

I think that first should be Comparable<?> first as we don't know what type we will get. However, if I make it Comparable<?> then that means second should be ? as well. I'm not sure how I can make second be of type ? as ? is not a type.

Is it possible to fix this issue?

Edit: first and second are compared inside check() using first.compareTo(second). We will always be comparing the same types (String to String, boolean to boolean, etc.) as second is given from a configuration file.

2

There are 2 answers

3
newacct On BEST ANSWER

It's not possible to do this in a type-safe way, because just because two objects are both Comparables doesn't mean they can compare to each other. You are getting objects which might be one of several different Comparable types (and you will only know which at runtime), and there is no commonality about what they can compare to; e.g. String can only compare to Strings, whereas BigDecimal can only compare to BigDecimals, so all you can say is that the object can compare to "something" (i.e. Comparable<?>), which is completely useless for compile-time type checking purposes.

You will only know whether one can compare to the other by running .compareTo() and seeing whether it produces a ClassCastException at runtime.

8
Madhan On

For that you have to extend the Comparable

    String x = "sdf", x2 = "sdf";
    int y = 55, y2 = 56;
    Boolean ob = true, ob2 = false;
    Compare compare = new Compare();
    compare.check(y2, y2);
    compare.check(ob, ob2);
    compare.check(x, x);

//For your case it will be
  Compare compare = new Compare();
  compare.check(convertStringValueToType(attribute.getValue(), attribute.getType()), convertStringValueToType(expectedValue.getFirst(), attribute.getType()));

class Compare<T extends Comparable> {

int check(T first, T second) {
    return first.compareTo(second);
}
}