繁体   English   中英

未经检查的强制转换:由 Class 包装的通配符到由 Class 包装的另一种类型

[英]Unchecked casting: Wildcard wrapped by Class to another type wrapped by Class

我正在尝试通过带有反射的注释标准收集类集(为了性能优势):

Reflections reflections = new Reflections(packagePrefix);
Set<Class<Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class);

问题是我得到的是Set<Class<?>>而不是Set<Class<Foo>> 我设法通过使用.filter(Foo.class::isAssignableFrom)过滤集合来检查该类是否为Foo类型。 在这一点上,我知道我正在使用Foo类型的类。 不幸的是,当从Class<?>Class<Foo>我得到了Unchecked 转换,我想避免这种情况。

这是完整的代码块:

Reflections reflections = new Reflections(packagePrefix);
Set<Class<Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class)
        .stream()
        .filter(Foo.class::isAssignableFrom)
        .map(uncheckedFoo -> {
          @SuppressWarnings("unchecked")
          Class<Foo> foo = (Class<Foo>) uncheckedFoo;
          return foo;
        })
        .collect(Collectors.toSet());

对此有何建议?

首先, Class<Foo>是用于准确表示类Foo的类对象,而不是其他类。 只能有一个Class<Foo>类型的对象。 所以拥有一Set它们是没有意义的。 看起来您正在收集一Set代表Foo及其子类的类对象。 在那种情况下,它应该是Set<Class<? extends Foo>> Set<Class<? extends Foo>>

其次,您需要将Class<?>类型的uncheckedFooClass<? extends Foo> Class<? extends Foo> 如果您不想使用未经检查的强制转换,您可以使用Class::asSubclass()以类型安全的方式执行此操作。 所以你可以做一些事情:

Set<Class<? extends Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class)
        .stream()
        .filter(Foo.class::isAssignableFrom)
        .map(uncheckedFoo -> uncheckedFoo.asSubclass(Foo.class))
        .collect(Collectors.toSet());

您可以使用一个很好的旧循环而不是流来向编译器明确表示每个项目在转换时都是assignableFrom Foo 否则,它会在下一步中忘记所有项目都是Foo类型。

铸件检查和铸件必须在 1 个步骤中

Set<Class<Foo>> foos = new HashSet<>();

for(Class<?> i : reflections.getTypesAnnotatedWith(
                   BooAnnotation.class ) )
{
  if(Foo.class.isAssignableFrom(i))
  {
    foos.add(Foo.class.cast(i)); //cast from Foo.class
  }
}

注意:您可以使用forEach而不是for(:)循环

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM