gpt4 book ai didi

Java集合、泛型和抽象类: concrete class information lost

转载 作者:行者123 更新时间:2023-12-01 19:47:08 25 4
gpt4 key购买 nike

我有类Bar(可能还有许多其他类),它扩展了抽象类AbstractFoo。将 Bar 实例转换为 FooDTO 时,会检测具体类。

但是,当将 Bar 实例集合转换为 FooDTO 列表时,具体的类信息会丢失,并且在 的基础上进行转换AbstractFoo.

这里出了什么问题?

public class CollectionGenericsNGTest {


public static abstract class AbstractFoo { }

public static class Bar extends AbstractFoo { }

public static class FooDTO {
final boolean isBar;

public FooDTO(AbstractFoo f) {
this.isBar = false;
}

public FooDTO(Bar b) {
this.isBar = true;
}
}

public static class FooDTOList {
List<FooDTO> list;

public FooDTOList(Collection<? extends AbstractFoo> source) {
list = source.stream()
.map(entry -> new FooDTO(entry))
.collect(Collectors.toList());
}

public List<FooDTO> getList() {
return list;
}
}

@Test
public void testDTO() {
Bar b = new Bar();
FooDTO f = new FooDTO(b);

assertTrue(f.isBar);
}

@Test
public void testDTO_abstract() {
AbstractFoo b = new Bar();
FooDTO f = new FooDTO(b);

assertTrue(f.isBar); // <-- fails, too
}

@Test
public void testDTOList() {
Bar b = new Bar();
List<Bar> collection = Arrays.asList(b);
FooDTOList list = new FooDTOList(collection);

FooDTO f = list.getList().get(0);
assertTrue(f.isBar); // <--- this fails!
}

}

最佳答案

这里

.map(entry -> new FooDTO(entry))

总是打电话

new FooDTO(AbstractFoo)

设置 this.isBar 的构造函数为假。

即使entry持有的对象运行时类型 Bar ,变量entry类型为AbstractFoo ,因为它是 Collection<? extends AbstractFoo> 的一部分,因此编译器知道该对象必须是 AbstractFoo ,但不知道它是Bar 。重载解析适用于编译时引用的类型,而不适用于运行时对象的类型。

如果你想检查 entry 所持有的对象的运行时类型,您可以考虑使用而不是变量类型

this.isBar = (f instanceof Bar);

当您分配给您的字段时。这将检查 f 引用的实际对象的运行时类型.

<小时/>

在你更简单的情况下

Bar b = new Bar();
FooDTO f = new FooDTO(b);

构造函数调用解析为 new FooDTO(Bar)因为您向它传递了 Bar 类型的引用.

如果您有:

AbstractFoo b = new Bar();
FooDTO f = new FooDTO(b);

那么构造函数调用将解析为 new FooDTO(AbstractFoo) ,因为您将传递 AbtractFoo 类型的引用.

关于Java集合、泛型和抽象类: concrete class information lost,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52758643/

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