gpt4 book ai didi

Java:使用显式子类数组调用 Vararg 方法

转载 作者:行者123 更新时间:2023-12-02 11:03:37 25 4
gpt4 key购买 nike

考虑以下示例,忽略人们想要这样做的原因:

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[] .

最佳答案

是的,当 WrapperOriginal 时,Wrapper[] 也是 Original[] >(当我意识到这一点时,我也很惊讶)。

您的 WrapperOriginal 的子类型,因为它扩展了 Original 类。

是的,如果被调用的方法尝试存储不是 Wrapper 的 Original,数组类型之间的子类型关系可能会引发 ArrayStoreException 到传递的数组中。但这在编译时不会被检查。据我了解,这正是我们拥有 ArrayStoreException 类型的原因,因为通常在编译时会捕获将错误类型存储到数组中的其他尝试。 the documentation of 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/

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