gpt4 book ai didi

java - 这个通用 Guice 绑定(bind)方法的 TypeLiteral 等价物有什么问题?

转载 作者:行者123 更新时间:2023-11-30 09:42:28 25 4
gpt4 key购买 nike

以下通用 Guice 绑定(bind)方法行为正确:

<T> Key<?> bindMultibinder(
ArrayList<Class<? extends T>> contents, Class<T> superClass) {
Named annotation = randomAnnotation();
Multibinder<T> options =
Multibinder.newSetBinder(binder(), superClass, annotation);
for (Class<? extends T> t : contents) {
options.addBinding().to(t);
}
final Key<?> multibinderKey = Key.get(Types.setOf( superClass ), annotation);
return multibinderKey;
}

并像这样使用客户端代码:

ArrayList<Class<? extends Option>> options = 
new ArrayList<Class<? extends Option>>();
options.add(CruiseControl.class);
bindMultibinder(options, Option.class);

但是,如果我想允许Option采用像 Option<Radio> 这样的通用参数,然后我假设我需要传递 TypeLiteralbindMultibinder父类(super class)参数。这是我迄今为止最好的尝试:

<T> Key<?> bindMultibinder(
ArrayList<TypeLiteral<? extends T>> contents, TypeLiteral<T> superClass) {
Named annotation = randomAnnotation();
Multibinder<T> options =
Multibinder.newSetBinder(binder(), superClass, annotation);
for (TypeLiteral<? extends T> t : contents) {
options.addBinding().to(t);
}
final Key<?> multibinderKey = Key.get(Types.setOf(superClass.getRawType()), annotation);
return multibinderKey;
}

与前一种情况等效的绑定(bind)代码如下所示:

ArrayList<TypeLiteral<? extends Option>> options = 
new ArrayList<TypeLiteral<? extends Option>>();
options.add(new TypeLiteral<CruiseControl>(){});
bindMultibinder(options, new TypeLiteral<Option>(){});

我几乎可以肯定下面的绑定(bind)是不正确的,因为 Types.setOf(superClass.getRawType())返回 ParameterizedType

final Key<?> multibinderKey = 
Key.get(Types.setOf(superClass.getRawType()), annotation);

关于如何正确创建集的任何想法?

最佳答案

ParameterizedType是 java 类,用于表示在 java 源代码中您需要用尖括号编写的类型:类似 Foo<Bar> 的类型或 Set<Option>Set<Option<Radio>>甚至 Set<? extends Option<Radio>> .这就是你想要的返回值。

您所做的实际上将与您想要调用的非常小的更改一起正常工作 superClass.getType()在倒数第二行而不是 superClass.getRawType() .话虽这么说,但我在这里还有一些其他建议。

首先,在您的第一种方法中,我将其更改为:

<T> Key<Set<T>> bindMultibinder(
Iterable<? extends Class<? extends T>> contents, Class<T> superClass) {
Named annotation = randomAnnotation();
Multibinder<T> options =
Multibinder.newSetBinder(binder(), superClass, annotation);
for (Class<? extends T> t : contents) {
options.addBinding().to(t);
}
@SuppressWarnings("unchecked")
final Key<Set<T>> multibinderKey = (Key<Set<T>>) Key.get(Types.setOf( superClass ), annotation);
return multibinderKey;
}

这会让你像这样调用:

bindMultibinder(ImmutableList.of(CruiseControlSubOptOne.class,
CruiseControlSubOptTwo.class),
Option.class);

或者,如果您不使用 guava - 虽然你应该 - 你可以使用 Arrays.asList而不是 ImmutableList.of .您可以获得与以前相同的类型安全性,而无需在绑定(bind)代码中声明所有这些尖括号。

如果 bindMultibinder 的来电者不多然而,我也会交换参数的顺序,但这可能只是个人风格问题。

通过这些相同的更改,您的第二种方法变为:

<T> Key<Set<T>> bindMultibinder(
Iterable<? extends TypeLiteral<? extends T>> contents, TypeLiteral<T> superClass) {
Named annotation = randomAnnotation();
Multibinder<T> options =
Multibinder.newSetBinder(binder(), superClass, annotation);
for (TypeLiteral<? extends T> t : contents) {
options.addBinding().to(t);
}
@SuppressWarnings("unchecked")
final Key<Set<T>> multibinderKey = (Key<Set<T>>) Key.get(Types.setOf(superClass.getType()), annotation);
return multibinderKey;
}

你可以类似地使用它:

bindMultibinder(ImmutableList.of(
new TypeLiteral<CruiseControlSubOptOne>() {},
new TypeLiteral<CruiseControlSubOptTwo>() {}),
new TypeLiteral<Option>() {});

尽管现在想想,我想知道你是否真的想要重载 bindMultibinder这需要 TypeLiteral .你不想拥有一个需要 Key 的人吗?相反?

<T> Key<Set<T>> bindMultibinder(Iterable<? extends Key<? extends T>> contents, Key<T> superClass) {
Named annotation = randomAnnotation();
Multibinder<T> options =
Multibinder.newSetBinder(binder(), superClass.getTypeLiteral(), annotation);
for (Key<? extends T> t : contents) {
options.addBinding().to(t);
}
@SuppressWarnings("unchecked")
final Key<Set<T>> multibinderKey =
(Key<Set<T>>) Key.get(Types.setOf(superClass.getTypeLiteral().getType()), annotation);
return multibinderKey;
}

毕竟,您可以用几乎相同的方式调用此方法:

bindMultibinder(ImmutableList.of(
new Key<CruiseControlSubOptOne>() {},
new Key<CruiseControlSubOptTwo>() {}),
new Key<Option>() {});

除了KeyTypeLiteral 更容易输入,并且如果您需要放入仅由其注释标识的内容,那将是微不足道的:

bindMultibinder(ImmutableList.of(
new Key<CruiseControlSubOptOne>() {},
new Key<CruiseControlSubOptTwo>() {},
Key.get(CruiseControl.class, Names.named("ThirdOpt")),
Key.get(CruiseControl.class, Names.named("FourthOpt"))),
new Key<Option>() {});

现在,是@Suppress让你紧张?良好的直觉。

不幸的是,可悲的事实是,在处理泛型类型周围的反射时(其中带有尖括号的类型),您几乎肯定会有一些未检查的小位。我的建议是让需要抑制非类型化警告的部分尽可能小,并尽可能多地向外界公开类型信息。如果您返回 Key<?>从这里开始,您可能会让此方法的调用者在尝试使用您的返回值时抑制未类型化警告。最好在此处执行此操作,您可以将警告抑制限制在一行,并且可以证明转换是安全的。

关于java - 这个通用 Guice 绑定(bind)方法的 TypeLiteral 等价物有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8683652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com