Общий код Java
Я новичок в дженериках. Вы можете видеть, что я повторяю некоторый код, зная точный тип val
, filterSmall
, filterGreat
. Я хочу написать общий код для сравнения val
с значениями фильтра. Я мог бы написать что-то вроде этого
private <T> boolean compareAgainstFilters(T val, T filterSmall, T filterGreat) {
if (!(filterSmall != null && filterSmall <= val)) {
return true;
}
if (!(filterGreat != null && val <= filterGreat)) {
return true;
}
return true;
}
но во время компиляции java не знает, действителен ли оператор <=
для типа T
.
Я не хочу повторять код, так как я могу это сделать?
if (value != null) {
switch (value.getClass().getName()) {
case "java.lang.Long":
Long filterSmall = (Long) filterSmaller;
Long filterGreat = (Long) filterGreater;
Long val = (Long) value;
if (!(filterSmall != null && filterSmall <= val)) {
return true;
}
if (!(filterGreat != null && val <= filterGreat)) {
return true;
}
break;
case "java.lang.Float":
Float filterSmallFloat = (Float) filterSmaller;
Float filterGreatFloat = (Float) filterGreater;
Float valFloat = (Float) value;
if (!(filterSmallFloat != null && filterSmallFloat <= valFloat)) {
return true;
}
if (!(filterGreatFloat != null && valFloat <= filterGreatFloat)) {
return true;
}
}
}
Ответы
Ответ 1
Вы можете использовать интерфейс Comparable
для сравнения чисел, поскольку все классы-оболочки для числовых примитивов реализуют его:
private <T extends Comparable<T>> boolean compareAgainstFilters(T val, T filterSmall, T filterGreat) {
if (!(filterSmall != null && filterSmall.compareTo(val)<=0)) {
return true;
}
if (!(filterGreat != null && val.compareTo(filterGreat)<=0)) {
return true;
}
return true;
}
<T extends Comparable<T>>
ограничивает типы, которые могут использоваться как аргументы типа вместо T. В этом случае они должны реализовать Comparable<T>
.
Ответ 2
Вы не можете использовать операторы <
или >
в общем методе. Обычно, когда переменная имеет тип Float
или Long
, компилятор принимает оператор после выполнения автоматического преобразования unboxing (чтобы получить примитивный тип) в скомпилированном коде. Другими словами,
filterSmall <= val
скомпилирован для:
filterSmall.longValue() <= val.longValue()
В универсальном методе компилятор не может применять преобразование распаковки. Единственный способ выполнить сравнение состоит в том, чтобы параметр типа расширял интерфейс Comparable
и использовал метод compareTo
. Обратите внимание, что типы Float
, Long
и т.д. Уже реализуют этот интерфейс.