Общий код 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 и т.д. Уже реализуют этот интерфейс.