
Question:
How can I use relational operators with Java number generics?
public class Test<K extends Number>{
private K key;
public boolean f (int i){
return i < key; //ERROR
}
public boolean g (K k){
return k < key; //ERROR
}
}
Is there any solution for it? compareTo?
Answer1:The easiest solution would be marking K
to extend Number
and implement Comparable<K>
:
public class Test<K extends Number & Comparable<K>>{
private K key;
public boolean f (int i) {
if (!(key instanceof Integer)) {
return false;
}
return new Integer(i).compareTo((Integer)key) < 0;
}
public boolean g (K k){
return k.compareTo(key) < 0;
}
}
Answer2:The <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.20.1" rel="nofollow">Java Language Specification</a> states
<blockquote>The type of each of the operands of a numerical comparison operator <strong>must be a type that is convertible (§5.1.8) to a primitive numeric type</strong>, or a compile-time error occurs.
</blockquote>and
<blockquote>A type is said to be <strong>convertible to a numeric type</strong> if it is a numeric type (§4.2), or it is a <strong>reference type that may be converted to a numeric type by unboxing conversion.</strong>
</blockquote>These <a href="http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.8" rel="nofollow">reference types are</a>
<blockquote>From type Boolean
to type boolean
From type Byte
to type byte
From type Short
to type short
From type Character
to type char
From type Integer
to type int
From type Long
to type long
From type Float to type float
From type Double
to type double
Since all you know about K
is that it is a subclass of Number
and therefore not guaranteed to be any of the above, you cannot use a reference of type K
as an operand of the <
operator.
You would have to devise a strategy with the Comparable
interface depending on what you are trying to achieve and how types should be compared.