Я хотел бы написать метод, который принимает обобщенный Number
в качестве аргумента и возвращает другой Number
, тип которого может отличаться от первого и передается в качестве второго аргумента.Примерно так:
public <N1 extends Number, N2 extends Number> N2 op(N1 num, Class<N2> retType) {
//Sample operation, where type conflicts arise.
return retType.cast(num + 3);
}
Конечно, я не могу просто разыграть N1
на N2
, если они, скажем, Integer
и Long
.Тем не менее, Number
предлагает doubleValue()
, intValue()
, ..., методы, которые могут позволить мне частично обойти проблему с помощью оператора switch / case.Это ограничило бы меня типами возврата xxxValue()
методов, которые предоставляет класс Number
, таким образом, обрезая AtomicInteger
, AtomicLong
, BigInteger
и BigDecimal
.
Это все еще приемлемо для приложения, которое я имею в виду, но мои методы не смогут должным образом обрабатывать любые пользовательские или будущие официальные расширения класса Number
, если не использовать оператор default
вблок switch / case, который должен произвольно решить, какой метод xxxValue()
вызывать, или вызвать исключение (которого я хотел бы избежать).Я мог бы использовать перечисление для инкапсуляции параметров по типу, но я боюсь, что мой код получился бы слишком запутанным и хитрым для использования.
Ответ на на этот вопрос дает дополнительное понимание относительно объявленияодин универсальный тип для двух параметров (он не гарантирует, что оба параметра на самом деле будут одного и того же типа во время выполнения), что, безусловно, стоит упомянуть здесь.
То, чего я хочу достичь, это:
- Объявите метод с некоторыми универсальными (в широком смысле)
Number
параметрами, возможно, с большим количеством параметров с другим числом параметров (например, метод с двумя, метод стри параметра), но все еще являются общими для каждого из них. - Параметры должны быть ограничены некоторыми известными расширениями
Number
(например, Integer
, Double
). - параметры могут входить в несколько комбинаций, потенциально любой из
(Double, Integer)
, (Double, Double)
, (Integer, Double)
, (Integer, Integer)
.
Я не хотел бы определять несколько методов с разными сигнатурами.Даже при фиксированном типе возвращаемого значения, например, Double
, число методов будет увеличиваться по мере добавления аргументов и типов.
Конечно, я всегда могу прибегнуть к конкретным, специальным реализациям для каждого метода, поскольку мне, вероятно, не понадобится каждая возможная комбинация типов.Я все еще хотел бы, чтобы мой дизайн был достаточно гибким при соблюдении этих ограничений типов.