Обобщения Java и класс Number - PullRequest
       24

Обобщения Java и класс Number

10 голосов
/ 13 октября 2010

Я хочу создать метод, который сравнивает число, но может иметь вход, который является любым из подклассов числа.1004 *

Мне нужно получить фактическое первичное значение, прежде чем я смогу выполнить сравнение, у класса Number есть методы для извлечения этого для каждого примитива, но я хочу чистый способ выбрать правильный.возможно?

Ура

Ответы [ 5 ]

9 голосов
/ 13 октября 2010

API Number не предлагает чистого способа получить значение;Вы должны использовать instanceof.

. Одним из решений является «сворачивание» значений в два типа: long и double.Таким образом, вы можете использовать этот код:

if( inputNumber instanceof Float || inputNumber instanceof Double ) {
    double val = inputNumber.doubleValue();
    ...
} else {
    long val = inputNumber.longValue();
    ...
}

Обратите внимание, что это работает только для стандартных типов чисел, но Number также реализовано многими другими типами (AtomicInteger, BigDecimal).

Если вы хотите поддерживать все типы, уловка заключается в использовании BigDecimal:

BigDecimal value = new BigDecimal( inputNumber.toString() );

Это должно всегда работать и давать вам наиболее точный результат.

4 голосов
/ 13 октября 2010

К сожалению, нет способа получить примитивный тип из типа оболочки, не прибегая к блокам if / else.

Проблема в том, что просто невозможно реализовать такой метод в общем виде. Вот несколько, казалось бы, возможных подходов, которые можно ожидать найти в классе Number:

public abstract X getPrimitiveValue();

Это было бы неплохо, не так ли? Но это невозможно. Не существует возможных X, которые могли бы быть абстракцией над int, float, double и т. Д.

public abstract Class<?> getCorrespondingPrimitiveClass();

Это тоже не поможет, потому что нет способа создания экземпляров примитивных классов.

Таким образом, единственное, что вы можете сделать, общее для всех типов, - это использовать методы longValue() или doubleValue(), но в любом случае вы теряете информацию, если имеете дело с неправильным типом.

Так что нет: иерархия java просто не подходит для общего решения таких проблем.

2 голосов
/ 31 октября 2010

Если вы просто сравниваете аргумент с другим значением того же параметра типа, то вы можете сделать следующее (просто добавив T x для простоты)

   public static <T extends Number & Comparable<? super Number>> int evaluate(T inputNumber, T x) {
          if (inputNumber.compareTo(x) > 0) { ... }
   }
2 голосов
/ 13 октября 2010

Методы с <T extends Number> всегда являются проблемой, так как вы не можете ничего сделать с числом (все операторы определены для дочерних элементов).Вам нужно будет либо сделать тонну instanceof для каждого дочернего элемента Number и обработать этот случай, приведя к подтипу.Или (лучше, я думаю, именно так Sun это делает), чтобы просто иметь метод для каждого дочернего типа, возможно, используя преимущества бокса / распаковки для таких операторов, как +, -,> и т. Д., Где это возможно (все обертки, недля BigInteger / BigDecimal или любых других типов).

0 голосов
/ 13 октября 2010

в этом случае вы можете использовать обычный метод без генериков

...