Могу ли я выполнять арифметические операции над базовым classом Number?

Я пытаюсь создать общий class на Java, который будет выполнять операции над числами. В следующем примере добавим следующее:

public class Example  { public T add(T a, T b){ return a + b; } } 

Простите мою наивность, поскольку я относительно новичок в Java Generics. Этот код не скомпилирован с ошибкой:

Оператор + не определен для типа (ов) аргумента T, T

Я думал, что с добавлением «extends Number» код будет компилироваться. Можно ли сделать эту Java или мне придется создавать переопределенные методы для каждого типа Number?

Номер не имеет связанного с ним оператора +, а также не может быть, поскольку нет перегрузки оператора.

Было бы неплохо.

В принципе, вы запрашиваете java для autobox descemant of Number, который включает в себя Integer, Float и Double, который может быть автобоксирован и иметь примененный оператор plus, однако может быть любое количество других неизвестных потомков Number, которые не могут быть автобоксированными , и это невозможно узнать до выполнения. (Проклятое стирание)

Ваша проблема не связана с дженериками, а не с операторами, примитивами против объектов и автобоксингами.

Думать об этом:

 public static void main(String[] args) { Number a = new Integer(2); Number b = new Integer(3); Number c = a + b; } 

Вышеприведенное не компилируется

 public static void main(String[] args) { Integer a = new Integer(2); Integer b = new Integer(3); Number c = a + b; } 

Вышеприведенное компилируется, но только из-за автобоксинга – своего рода хакерский синтаксический клей, введенный в Java 5, и работает только (во время компиляции) с некоторыми конкретными типами: например, int-Integer.

За кулисами компилятор Java переписывает последнее утверждение («Я должен распаковать a и b чтобы применить оператор sum с примитивными типами данных и поместить результат для присвоения ему объекту c »), таким образом:

  Number c = Integer.valueOf( a.intValue() + b.intValue() ); 

Java не может распаковать Number потому что он не знает во время компиляции конкретного типа и, следовательно, не может угадать его примитивную копию.

Вы можете сделать что-то подобное

  class Example  { public Number add(T a, T b){ return new Double(a.doubleValue() + b.doubleValue()); } } 

Да, Натан прав. Если вам нужно что-то подобное, вы должны сами написать

 public class Example  { private final Calculator calc; public Example(Calculator calc) { this.calc = calc; } public T add(T a, T b){ return calc.add(a,b); } } public interface Calculator { public T add(T a, T b); } public class IntCalc implements Calculator { public final static IntCalc INSTANCE = new IntCalc(); private IntCalc(){} public Integer add(Integer a, Integer b) { return a + b; } } ... Example ex = new Example(IntCalc.INSTANCE); System.out.println(ex.add(12,13)); 

Слишком плохо Java не имеет classов classов (Haskell) или неявных объектов (Scala), эта задача будет идеальным вариантом использования …

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

Вы можете проверить, являются ли a и b экземпляром Long / Double / Integer / etc. и делегировать добавление к таким методам, как:

 public Integer add(Integer a, Integer b) { return a+b; // this actually uses auto boxing and unboxing to int } 

И вам нужно будет создать один для каждого типа, который расширяет число, поэтому это не реально. Другими словами, не используйте generics для числовых операций. Номер как суперclass довольно ограничен.

Рассмотрим Example , как бы работать + над этим? В Number нет и не add ни одного или даже подобных Integer .

Хуже считают, что final class FunkyNumber extends Number { ... weird stuff, no add op ... } .

Даже в библиотеке времени исполнения Java есть эта проблема, большинство методов, связанных с примитивами, должны дублировать одну и ту же функциональность.

Самый быстрый вариант – записать код для одного типа, а затем скопировать его и заменить тип для генерации методов для других типов. Для этого достаточно короткого сценария.

  • Есть ли способ разбивки запросов путем комбинирования курсоров запросов с использованием FirestoreRecyclerAdapter?
  • цвет андроида между двумя цветами, в зависимости от процента?
  • Преобразование JSONArray в String Array
  • Android имитирует нажатие клавиши
  • Показывать только две цифры после десятичной
  • java.lang.ClassNotFoundException: Не нашел class на пути: dexpathlist
  • Android FTP Library
  • Ошибка вызывает виртуальный метод 'double android.location.Location.getLatitude ()' в ссылке на нулевой объект
  • Папка SRC в Eclipse пуста (class MainActivity не создан) после создания нового проекта андроида с использованием Eclipse
  • Чтение Android из streamа ввода эффективно
  • Завершить все предыдущие действия
  • Interesting Posts

    Как сделать объединение, пересечение, разность и обратные данные в java

    Как я могу освободить указатель мыши с помощью мыши в OS X?

    Можно ли отменить транзакцию, которую я уже совершил? (потери данных)

    Как скрыть курсор в приложении Swing?

    Как установить конкретные ячейки, чтобы не вычислять в Excel?

    Столбец автоинкремента MySQL перескакивает на 10 – почему?

    Проверьте, повреждены ли файлы PDF с помощью командной строки в Linux

    Как добавить пользовательский заголовок Http для веб-службы C #, использующий веб-службу Axis 1.4

    Мой SearchIndexer.exe падает каждый день

    Местоположение AngularJS $ не меняет путь

    Почему LayoutInflater игнорирует параметры layout_width и layout_height, которые я указал?

    JQuery JQGrid – Как установить выравнивание ячеек заголовка сетки?

    Макрос для экспорта таблиц MS Word в листы Excel

    jqGrid – Как изменить конструкцию form_editing?

    Какова категория значений операндов операторов C ++, когда они не указаны?

    Давайте будем гением компьютера.