【问题标题】:If an array of Object is an Object, why is an array of String not a String如果对象数组是对象,为什么字符串数组不是字符串
【发布时间】:2016-06-08 07:46:29
【问题描述】:

对象类是Java中每个类的超类。所以每个类都应该具有 Object 类的属性或行为。

然后我们可以声明对象数组,如下所示:

Object c = new Object[] {1,2,"22" };

那么当谈到 String 为什么下面的声明是错误的:

String s = new String[]{"s","s"};

【问题讨论】:

  • new String[]{"s","s"} 的类型是 String[],而不是 StringObject[]Object 的子类,这就是第一个有效的原因。
  • String[] s = new String[]{"s","s"};
  • @AndyTurner 好的,那么String[] 不是String 的子类。
  • @HarikaChoudaryKanikanti 正确。这通常适用于数组类型(Object[]Object 除外);而且String 是一个final 类,所以它有no 子类。
  • 由于没有人指出,这个版本更干净,同样有效:String[] s = {"s","s"};

标签: java


【解决方案1】:

new String[]{"s","s"} 的类型是 String[],而不是 StringT[] 不是 T 的子类(除非 T 恰好是 Object)。

Object[]Object 的子类型,这就是第一个有效的原因。事实上,所有数组类型都是subtype of Object,包括可能令人惊讶的基元数组,例如int[],尽管int 不是Object (*)。

您可以使用更具体的类型编写第一个:

Object[] c = new Object[] {1,2,"22" };

您可以将第二个写成以下任何一种:

String[] s1 = new String[]{"s","s"};
Object[] s2 = new String[]{"s","s"};
Object s3 = new String[]{"s","s"};

顺便提一下,s2 证明了 Java 中的数组是协变的。这是有问题的,因为你可以合法地写:

s2[0] = new Object();

这会在运行时失败并显示 ArrayStoreException,因为您不能将 Object 引用存储在 String[] 中。

这就是为什么像 Josh Bloch 这样的作者给出建议“优先使用列表而不是数组”的原因之一(参见 Effective Java 2nd Ed 第 25 条),因为像 List 这样的 Java 集合不是协变的,所以不会遇到同样的问题。


(*) 只是为了增加混淆,原始数组不是Object[] 的子类型,因为原始数组不是Object 的子类型。例如,编写时会出现编译时错误:

Object[] illegal = new int[5];

【讨论】:

    【解决方案2】:

    有点令人困惑,Object[] Object。 (一方面这是 Java 如何实现零长度数组,并允许数组作为函数返回值)。

    因此将Object[] 实例分配给Object 类型的引用是有意义的。

    但是将String[] 实例分配给String 类型的引用确实有意义。 (但请注意,String[]也是Object。)

    所以

    1. Object c = new Object[] {1,2,"22" }; 有道理
    2. String s = new String[]{"s","s"}; 没有意义
    3. Object s = new String[]{"s","s"}; 有道理

    【讨论】:

      【解决方案3】:

      它的基本 Java 原理,Everything 是一个Object,因此你可以使用对象引用来做任何事情,比如 Object o = new AnyOtherClass()

      您可以将类的引用用于其子类,例如 List l = new Arraylist()

      但是 String[] 是 Array 并且 Array 不是 String 的祖先

      【讨论】:

        【解决方案4】:

        array 是对象的集合或原始数据类型的集合,而 string 是字符序列。如您所知, object 是所有其他类的超类,这就是您执行以下操作的原因: Object c = new Object[] {1,2,"22" };

        String 类不是数组类型的超类...所以你不能像下面这样执行..

        String s = new String[]{"s","s"};
        

        希望这对你有帮助...

        【讨论】:

          【解决方案5】:
          Object c = new Object[] {1,2,"22" };
          

          是有效的,因为Objects 的数组仍然是Object。您也可以在声明级别指定 cObjects 的数组,如下所示:

          Object[] c = new Object[] {1,2,"22" };
          

          然而,

          String s = new String[]{"s","s"};
          

          无效,因为Strings 的数组不是String。您需要将数组转换为String,如下所示:

          String s = String.join(",", new String[]{"s","s"});
          

          或将其存储为数组,如下所示:

          String[] s = new String[]{"s","s"};
          

          【讨论】:

            【解决方案6】:

            首先,数组保存堆中值的引用。

            第二,Object类是java中所有其他类的母类。 所以对象数组可以保存任何类型的引用值,但字符串数组只能保存字符串数据类型的引用,并且每个引用都引用单独的字符串(string[0]= "a",string[1]="stackOverFlow"...)

            第三,字符串是java中的一个字符序列。

            所以,字符串数组不能是字符串,因为它不是指字符序列,而是指驻留在堆中的对象的字符串类型。

            【讨论】:

              猜你喜欢
              • 2012-10-23
              • 2023-03-26
              • 2022-12-02
              • 2010-10-04
              • 1970-01-01
              • 1970-01-01
              • 2022-06-29
              • 2015-10-15
              • 1970-01-01
              相关资源
              最近更新 更多