- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我使用泛型时,某些类出现错误。我指定了出现错误的位置。我无法摆脱它。我尝试了 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#1 和 capture#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/
我是一名优秀的程序员,十分优秀!