5

我来自C背景。我不能将 an 添加ObjectObject[]in对我来说没有意义foo()

我希望函数中的代码foo可以在运行时工作,但是main()当我尝试这样做时会失败,strings[0].toLowerCase();因为 in 中的对象strings[0]不是 aString但实际上是 aStringBuilder没有toLowerCase(). 在一天结束时,我将一个指针存储到一个指针数组中,并且该行objects[0] = other不应该是无效的。很明显,我对 java 的理解是错误的(但我现在还很新)。

class Main {

    static void foo(Object[] objects, Object other) {
        objects[0] = other;
    }
    public static void main(String[] args) {
        String[] strings = { "stringValue" };
        foo(strings, new StringBuilder());
    }
}

编辑:谢谢大家的回答。感谢@Andy Turner,我在谷歌上搜索了“数组的java协方差”,并遇到了讨论这种行为的问题。诀窍是编译器和运行时处理代码的方式非常不同。编译器对代码很好,运行时不是。

4

3 回答 3

4

从以下文档ArrayStoreException

抛出以指示已尝试将错误类型的对象存储到对象数组中。例如,以下代码生成 ArrayStoreException:

Object x[] = new String[3];
x[0] = new Integer(0);

仅仅因为您将 a 传递给String[]期望 an 的方法Object[]并不意味着它实际上是Object[]. 因为您创建了 a String[],所以您只能为其添加实例String,而您正在尝试添加 a StringBuilder,这没有任何意义。

String[]请注意,如果您将 的类型更改为 ,它不会引发异常Object[]

public static void main(String[] args) {
    Object[] strings = { "stringValue" };
    foo(strings, new StringBuilder()); // Perfectly fine
}
于 2018-06-10T15:58:50.450 回答
1

在运行时评估您的字符串数组实际上是在尝试分配不同的类型。你会一个ArrayStoreException,这清楚地表明

抛出以指示已尝试将错误类型的对象存储到对象数组中。例如,以下代码生成 ArrayStoreException:

Object x[] = new String[3];
 x[0] = new Integer(0);

接受 Object 类型作为参数甚至方法/函数的返回值通常不是一个好习惯。它们可能是多态接口,但 Object 处于最高抽象级别,不适合此目的。

于 2018-06-10T16:01:27.003 回答
0

您正在尝试将对象“StringBuilder”添加到对象“String”的数组中。在某些情况下,如果您要分配 StringBuilder 值,这实际上可能有效,但我不会对此表示担忧,因为我自己从未使用过它。这是一个很好的阅读:https ://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html

通常 Java 会为您处理指针,这使得它很难搞砸。

我希望我能帮助你:)

于 2018-06-10T16:06:25.610 回答