我有这些类的方法:
public abstract class Bar<T extends Bar> {
Foo myFoo;
public Optional<Foo> findFoo() { return Optional.ofNullable(this.myFoo); }
}
public class Baz extends Bar<Baz> {
}
,其中Foo是具体的最终类,o是扩展Bar的对象。
可以通过这种方式获得单位测试中的值:
Bar bar = new Baz();
Optional<Foo> optinalFoo = bar.findFoo();
Foo foo = optionalFoo.get();
但是,直接调用类型信息时会丢失:
Foo foo = bar.findFoo().get();
在第二个例子中,编译器认为get()返回一个Object而不是一个Foo。为什么?有没有办法以其他方式向编译器提供类型信息?
(我知道你应该避免直接调用get(),但由于这是在单元测试中,如果它会引发意外结果,那就没关系。)
答案 0 :(得分:0)
Bar bar
是原始类型。原始类型没有任何通用信息,它是一个全有或全无的东西。没有一个好的,通用的后退。一个例子是
Map<String, String> map = new HashMap<>();
Set<Map.Entry<String, String>> entries = map.entrySet();
// however when you use a raw type there is no generic.
Map map2 = new HashMap();
Set<Map.Entry> entries2 = map2.entrySet(); // doesn't work
Set entries2 = map2.entrySet(); // does work
这是因为原始类型仅用于向后兼容。在Java 5.0之前的版本中没有泛型,因此您不得不期望原始类型没有任何泛型。
答案 1 :(得分:0)
bar
变量使用原始类型,因此它缺少所有泛型类型检查。定义类型Optional<Foo> optionalFoo
您还有未经检查的赋值(这意味着类型将仅在运行时检查),但编译器会看到类型,.get()
工作正常。要解决此问题,您需要定义通用参数,例如:
Bar<? extends Bar> bar = new Baz();