- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑以下示例,忽略人们想要这样做的原因:
private static class Original {
public String getValue() {
return "Foo";
}
}
private static class Wrapper extends Original {
private Original orig;
public Wrapper(Original orig) {
this.orig = orig;
}
@Override
public String getValue() {
return orig.getValue();
}
}
public static void test(Original... o) {
if (o != null && o.length > 0) {
for (int i = 0; i < o.length; i++) {
if (o[i] instanceof Wrapper) {
o[i] = ((Wrapper) o[i]).orig; // Throws java.lang.ArrayStoreException at runtime
}
}
}
}
public static void main(String[] args){
test(new Wrapper[] { // Explicitly create an array of subclass type
new Wrapper(new Original())
});
}
此示例在编译时没有给出警告或错误。编译器似乎决定 Wrapper[]
包含Wrapper
实例,这实际上意味着这些肯定是 Original
的实例类(class)。这完全没问题。
但是,在运行时,Wrapper[]
实例直接传递到方法中。我认为拆除这个数组并重新创建 Original[]
的实例会足够聪明。在运行时,但似乎情况并非如此。
此行为是否曾在某个地方(例如 JLS)记录过?像我这样的普通程序员总是假设我可以操纵 Original...
的 vararg 参数。就好像它是 Original[]
.
最佳答案
是的,当 Wrapper
是 Original
时,Wrapper[]
也是 Original[]
>(当我意识到这一点时,我也很惊讶)。
您的 Wrapper
是 Original
的子类型,因为它扩展了 Original
类。
是的,如果被调用的方法尝试存储不是 Wrapper 的
到传递的数组中。但这在编译时不会被检查。据我了解,这正是我们拥有 ArrayStoreException 类型的原因,因为通常在编译时会捕获将错误类型存储到数组中的其他尝试。 the documentation of Original
,数组类型之间的子类型关系可能会引发 ArrayStoreException
ArrayStoreException
中有一个很好的简短示例。 。该示例还表明,它与可变参数或方法调用没有任何关系,它适用于所有数组。
Java 语言从版本 1 开始就是这样设计的(顺便说一句,这早在可变参数被引入之前)。感谢 Andy Turner 找到了 Java 语言规范 (JLS) 引用:它位于 section 4.10.3 Subtyping among Array Types :
If S and T are both reference types, then S[] >_1 T[] iff S >_1 T.
关于Java:使用显式子类数组调用 Vararg 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51147638/
我是一名优秀的程序员,十分优秀!