#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 один? И как это сделать грамотно?
Ответы
Ответ 1
Что не так с генериками уже объяснили. Я же представлю вариант выхода из безвыходной ситуации с одним switch-ом. Сделайте из Number BigDecimal. У него есть методы, реализующие арифметические операции. Складывайте, вычитайте, умножайте и делите BigDecimal в одном switch-е, а результат переведите обратно в int или double: publicT 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 с успехом применить. Ответ 2
Вообще это проблема не про Generic, а про autoboxing. У классов Integer и Double тоже не определено ни одной арифметической операции и если вы попробуете скомпилировать код вида: void add(Integer b, Integer c){ Integer a = b + c; } В Java 1.4, то у вас ничего не получится, такой код начинает работать только с версии 1.5, когда собственно и появился autoboxing. И в Java 1.5 в байт коде будет: void add(Integer b, Integer c) { Integer a = Integer.valueOf(b.intValue() + c.intValue()); } А т.к. для класса Number нельзя заранее определить как его преобразовать, то и арифметическую операцию применить нельзя.
Комментариев нет:
Отправить комментарий