Если вы вычисляете его на основе аргументов времени выполнения, он больше не литерал : это просто тип.
Несмотря на то, что вы могли бы использовать эквивалентный каркас Guava для TypeToken и его утилит, в Guice есть встроенный класс утилит Type: com.google.inject.util.Types . Используйте newParameterizedType(Type rawType, Type... typeArguments)
для создания требуемого типа, отметив, что ParameterizedType и Class оба реализуют тип.
static ParameterizedType combineTypes(Class<?> typeOne, Class<?> typeTwo) {
return Types.newParameterizedType(MyClass.class, typeOne, typeTwo);
}
К сожалению, AbstractModule.bind
и LinkedBindingBuilder.to
не предлагают перегрузки для Type; просто Class, TypeLiteral и Key. К счастью, вы можете генерировать ключ отражательно, используя тип, используя Key.get(Type)
:
bind(Key.get(combineTypes(Foo.class, Bar.class))).to(MyClassFooBar.class);
Обратите внимание, что ParameterizedType сам по себе не является параметризованным типом. Это побеждает некоторые хитрые средства защиты на основе генериков, которые предлагает bind
EDSL от Guice. Для того чтобы вышеперечисленное сработало, вам может потребоваться @SuppressWarnings
, вернуть необработанный тип Key
или подумать о том, чтобы combineTypes
вернул Key<MyClass<T, R>>
(что потребовало бы приведения из возвращаемого значения Key.get(Type)
Key<?>
). Если вам действительно необходимо использовать TypeLiteral, вы можете создать TypeLiteral с помощью Key.getTypeLiteral , но для этого также потребуется приведение с TypeLiteral<?>
- и не будет «литералом типа» по любому значимому определению.