часть 1
Для этого нет удовлетворительного решения, поскольку java.lang.Number
не указывает ничего, что было бы полезно для вычисления преемника Number
.
Вы должны будете сделать instanceof
проверки для типов числовых ящиков и обработать каждый случай специально. Также обратите внимание, что вы можете получить instanceof Number
, который не относится ни к одному из типов числовых полей, например BigInteger
, AtomicLong
и потенциально неизвестные подклассы Number
(например, Rational
и т. Д.).
Часть 2
Смотри, здесь очень обманчиво. Эти 3 метода могут выглядеть одинаково, но автобокс / распаковка скрывает тот факт, что они на самом деле сильно отличаются на уровне байт-кода:
Integer plusOne(Integer);
Code:
0: aload_1
1: invokevirtual #84; //int Integer.intValue()
4: iconst_1
5: iadd
6: invokestatic #20; //Integer Integer.valueOf(int)
9: areturn
Double plusOne(Double);
Code:
0: aload_1
1: invokevirtual #91; //double Double.doubleValue()
4: dconst_1
5: dadd
6: invokestatic #97; //Double Double.valueOf(double)
9: areturn
Long plusOne(Long);
Code:
0: aload_1
1: invokevirtual #102; //Long Long.longValue()
4: lconst_1
5: ladd
6: invokestatic #108; //Long Long.valueOf(long)
9: areturn
Мало того, что 3 метода вызывают разные методы xxxValue()
и valueOf()
для разных типов, но и инструкция для помещения константы 1
в стек также различна (iconst_1
, dconst_1
и lconst_1
).
Даже если возможно связать универсальный тип, такой как <T=Integer|Long|Double>
, эти 3 метода не могут быть обобщены в один метод, поскольку они содержат очень разные инструкции.