Страницы

Поиск по вопросам

вторник, 23 апреля 2019 г.

Проблема с дженериками в java

Пытаюсь сделать так, чтобы выполнялось арифметическое действие, и, в зависимости от того, какое число должно выводиться на экран, метод возвращал или int или double.
реализую это так:
@FunctionalInterface public interface JoinMathAction { T mathAction(Number a, Number b); }
public class GoMath { public T getResultMath(T arg1, T arg2, String op) { Number res = 0;
if (arg1 instanceof Integer && arg2 instanceof Integer) { JoinMathAction mm = (a, b) -> { int argFirst = a.intValue(), argSec = b.intValue(); switch (op) { case "/": { if(argFirst == 0 || argSec == 0) { try { throw new DivZeroException("Ділення на 0 неможливе"); } catch (DivZeroException d) { System.out.println(d.getMessage()); } } else { return argFirst / argSec; } } case "*": { return argFirst * argSec;
} case "-": { return argFirst - argSec; } case "+": { return argFirst + argSec; } } return 0; };
res = mm.mathAction(arg1, arg2);
} else if (arg1 instanceof Double || arg2 instanceof Double) { JoinMathAction mm = (a, b) -> { double argFirst = a.doubleValue(), argSec = b.doubleValue(); double result = 0;
switch (op) { case "/": { if(argFirst == 0 || argSec == 0) { try { throw new DivZeroException("Ділення на 0 неможливе"); } catch (DivZeroException d) { System.out.println(d.getMessage()); } } else { return argFirst / argSec; } } case "*": { return argFirst * argSec; } case "-": { return argFirst - argSec; } case "+": { return argFirst + argSec; } } return result; };
res = mm.mathAction(arg1, arg2); } return (T) res; } }
Все работает, но как сделать с двух switch один? И как это сделать грамотно?


Ответ

Что не так с генериками уже объяснили. Я же представлю вариант выхода из безвыходной ситуации с одним switch-ом. Сделайте из Number BigDecimal. У него есть методы, реализующие арифметические операции. Складывайте, вычитайте, умножайте и делите BigDecimal в одном switch-е, а результат переведите обратно в int или double:
public T getResultMath(T arg1, T arg2, String op) { BigDecimal bigArg1 = new BigDecimal(arg1 instanceof Integer ? arg1.intValue() : arg1.doubleValue()); // или в любом случае используя doubleValue BigDecimal bigArg2 = new BigDecimal(arg2.doubleValue()); BigDecimal bigResult; switch (op) { ... case "*" : bigResult = bigArg1.multiply(bigArg2); break; ... } // Округления при переводе в int сами найдёте как сделать return (T) (arg1 instanceof Integer ? new Integer(bigResult.intValue()) : new Double(bigResult.doubleValue())); }
Вообще-то не обязательно использовать BigDecimal. Можно тот же double с успехом применить.

Комментариев нет:

Отправить комментарий