gpt4 book ai didi

java - Java 泛型的问题

转载 作者:行者123 更新时间:2023-12-01 17:40:13 25 4
gpt4 key购买 nike

当我使用泛型时,某些类出现错误。我指定了出现错误的位置。我无法摆脱它。我尝试了 Actor 阵容以及我能想到的一切。

class UltraTable<O extends Object> {
public void setContent(Collection<O> collection) {
}
}

class ObjectA {
}

class AShell {

protected UltraTable<? extends ObjectA> tableA;

protected List<? extends ObjectA> getAObjects() {
return null; // the list is created here
}
}

class BShell extends AShell {
public BShell() {
tableA.setContent(getAObjects()); // THE ERROR IS HERE!
}

}

如何通过仅更改 BShell 来使其工作类,如果可能的话?

我收到的错误消息是:

The method setContent(Collection<capture#1-of ? extends ObjectA>)  
in the type UltraTable<capture#1-of ? extends ObjectA>
is not applicable for the arguments (List<capture#2-of ? extends ObjectA>)
<小时/>

更新:

如果我按照 Thomas Jung 所说更改代码,我会在 tableA 的构造函数中的其他类中收到错误和方法getAObjects() :

class ObjectX extends ObjectA {} 
class XShell extends AShell {
public XShell() {
tableA = new UltraTable<ObjectX>();
tableA.setContent(getAObjects()); // THE SAME ERROR AS ABOVE
}
@Override
protected List<ObjectX> getAObjects() {
return null;
}
}

我经常有一个 UltraTable 和 getAObjects() 返回扩展 BaseClass 的 DerivedClass 列表。这应该适用于所有情况。

无论如何,我认为错误消息不合逻辑:“... <capture#1-of ? extends ObjectA> 不适用于参数 ( List<capture#2-of ? extends ObjectA> )”
capture#1capture#2 都扩展了 ObjectA!这里出了什么问题?

最佳答案

定义如下:

protected UltraTable<? extends ObjectA> tableA;
protected List<? extends ObjectA> getAObjects(){}

没有用。除了UltraTable<ObjectA>,你不能用它做更多的事情。 。这样的定义仅在您使用它(作为参数)时有用,而不是在生成它(作为返回值)时有用。例如定义:

public void setContent(Collection<? extends O> collection) {}

可能会有用。它现在可以使用 O 的集合及其所有亚型。

UltraTable<O extends Object>UltraTable<O> 相同。全部O将是 java.lang.Object 的子类。

这可以编译。我希望它仍然有意义。

class UltraTable<O> {
public void setContent(Collection<O> collection) {}
}
class ObjectA {}

class AShell {
protected UltraTable<ObjectA> tableA;
protected List<ObjectA> getAObjects() {
return null; // the list is created here
}
}

class BShell extends AShell {
public BShell() {
tableA.setContent(getAObjects());
}
}

更新:

Java 泛型是不变的。因此,唯一广泛适用的解决方案是更改代码,使 XShell 和 AShell 中的泛型类型参数相同。

class ObjectX extends ObjectA {} 
class XShell extends AShell {
public XShell() {
tableA = new UltraTable<ObjectA>();
tableA.setContent(getAObjects());
}
@Override
protected List<ObjectA> getAObjects() {
return null;
}
}

这是有道理的。因为用 XShell 替换 AShell 是无效的:

AShell ashell;
List<ObjectA> aobjects = ashell.getAObjects();
aobjects.add(new ObjectA());

XShell xshell;
List<ObjectX> aobjects = xshell.getAObjects();
aobjects.add(new ObjectA()); //invalid: cannot cast to ObjectX

但是,如果您无法像使用 AShell 一样使用 XShell 重新定义的方法,则会破坏 Liskov substitution principle .

关于java - Java 泛型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1738071/

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