Ответ 1
Я подозреваю, что это ошибка в компиляторе. Он статически связан с Number.compareTo(Object)
, который не существует, когда он должен быть Comparable.compareTo(Object)
.
Скажем, у вас есть метод, который
он выглядит примерно так:
<N extends Number & Comparable<N>, S extends N> S ensureLessThan(N threshold, S input) {
if (input.compareTo(threshold) >= 0) {
throw new IllegalArgumentException("Input " + input + " is not less than " + threshold);
}
return input;
}
При запуске этот метод выдает NoSuchMethodError
:
Exception in thread "main" java.lang.NoSuchMethodError: java.lang.Number.compareTo(Ljava/lang/Object;)I
Добавление того, что выглядит как избыточный бросок, заставляет его работать:
...
if (((N) input).compareTo(threshold) >= 0) {
...
Итак, что здесь происходит?
UPDATE: моя версия Java
java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06-434-11M3909)
Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01-434, mixed mode)
И вот пример: https://gist.github.com/4526536
Я подозреваю, что это ошибка в компиляторе. Он статически связан с Number.compareTo(Object)
, который не существует, когда он должен быть Comparable.compareTo(Object)
.
if (threshold.compareTo(input) < 0) {
будет работать.
Конечно, это ошибка компилятора. Причина этого заключается в том, что компилятор генерирует проверенный листинг в Comparable. В то время как другой путь вокруг этого не делает.
ensureLessThan(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;
L0
LINENUMBER 11 L0
ALOAD 1
CHECKCAST java/lang/Comparable
ALOAD 2
INVOKEINTERFACE java/lang/Comparable.compareTo (Ljava/lang/Object;)I
IFGE L1
против
ensureLessThan(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;
LINENUMBER 11 L0
ALOAD 1
ALOAD 2
INVOKEVIRTUAL java/lang/Number.compareTo (Ljava/lang/Object;)I
IFGE L1
Что странно, следующий код компилируется и работает с моей стороны:
/**
* @author Buhake Sindi
* @since 14 January 2013
*
*/
public class Test {
public static <N extends Number & Comparable<N>, S extends N> S ensureLessThan(N threshold, S input) {
if (input.compareTo(threshold) >= 0) {
throw new IllegalArgumentException("Input " + input + " is not less than " + threshold);
}
return input;
}
public static void main(String[] args) {
ensureLessThan(10, 5);
}
}
Протестировано в Eclipse Juno (Java EE) со следующим JDK: