【问题标题】:Are Java arrays class instances?Java数组是类实例吗?
【发布时间】:2021-04-21 06:55:07
【问题描述】:

Java 语言规范says

对象是类实例或数组。

还有says:

数组 [...] 可以分配给 Object 类型的变量

但是the part that confuses me 是:

Object 类是所有其他类的超类

如果数组可以赋值给Object类型的变量,那么它一定意味着数组可以是Objects(不仅behave as,而是be)。那么就说明数组是一个类的实例,和第一个引号好像不一致(如果是,那为什么会被列为不同的东西呢?)。

这一切如何结合在一起?

【问题讨论】:

  • "那么它的意思是一个数组是一个类实例" - 不,第一个引号明确说“一个对象是一个类实例或 一个数组”。如果一个数组是一个类实例,那么“一个对象是一个类实例。”这句话就足够了。
  • 第一句中的英文单词object指的是一个通用对象,即。一些可以被感官感知的物质。第三句中的 Object 指的是特定的 Java 类 Object。 Java 类实例数组仍然是对象数组,即。物质的东西。
  • 是的,但是作为一个数组“可以分配给Object类型的变量”,这并不意味着数组不仅仅是一个对象,而是一个对象好吧,让句子“一个对象是一个类实例”就足够了吗?
  • 这能回答你的问题吗? Is an array an object in Java?
  • @AldánCreo JLS 在哪里声明“一个对象是一个类实例[Period]”?

标签: java arrays oop jls


【解决方案1】:

是的……也不是。确实,new Object[100] instanceof Objecttrue 是真的,但这缺少 Java 中数组的真正本质。数组是对象(小写),但不是对象(大写)。例如,作为对象,您必须使用new 运算符为它们分配空间。

然而,Java 语言规范说“对象是类实例或数组”是正确的,因为数组与常规对象根本不同。它们继承自 C++ 等语言,这些语言更深地植根于计算机的低级架构。

“数组 [...] 可以分配给 Object 类型的变量” 仅仅是因为 Java 为我们程序员提供了一个接口,可以将数组称为对象.其实JLS says

可以在数组上调用 Object 类的所有方法

这当然是对的,但在逻辑上并不意味着它们是对象。数组不是真正的对象;因此,它们不是真正的类实例,因此句子“类 Object 是所有其他类的超类” 在这里不适用。

总而言之,Java 不是一种纯粹的面向对象的编程语言(例如,基元不是对象,但它们仍然存在于 Java 中)。 数组是 Java 包含的一种语言特性,表现得好像它们是 Object 类的类实例,但 实际上并不是它的类实例.

[这是我试图总结这里的要点。非常感谢大家的想法,并随时添加更多!]

【讨论】:

    【解决方案2】:

    没有矛盾。 数组也是一个对象,尽管它是一种特殊的对象。
    就像在说:鸟也是一种动物,尽管是一种特殊的动物。

    您可以通过编译和运行以下 Java 代码来说服自己。

        String[] arrayOfStrings = { "bla", "blah" };
        
        // examine the class hierarchy of the array 
        System.out.println("arrayOfStrings is of type "
                + arrayOfStrings.getClass().getSimpleName()
                + " which extends from "
                + arrayOfStrings.getClass().getSuperclass().getSimpleName());
        
        // assingning the array to a variable of type Object
        Object object = arrayOfStrings;
    

    输出将是

    arrayOfStrings is of type String[] which extends from Object
    

    【讨论】:

      【解决方案3】:

      数组是 Java 本身提供给您的特殊类。它们都继承自公共超类Object。由于它们继承自Object,它们当然可以在任何需要Object 的地方使用。数组的实例确实是这些类的实例。甚至可以像引用其他类的字面量一样引用数组类:

          Class<int[]> intArrayClass = int[].class;
      

      我认为没有冲突。

      这很有用https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.8

      【讨论】:

      • 正如@Turing85 所说,“如果一个数组是一个类实例,那么“一个对象是一个类实例。”这句话就足够了。”
      • 是的,有些多余的句子,不是绝对最优的定义
      【解决方案4】:

      您的second link 还说:

      可以在数组上调用 Object 类的所有方法。

      因此,至少从开发人员的 POV 来看,它是一个 Object,尽管没有实例化 java.lang.Array(向我们公开)。

      第二个迹象是数组也存储在堆上。

      【讨论】:

      • "...至少,它是一个Object,虽然没有java.lang.Array(向我们公开)..." - 怎么样,例如, String[].class?
      • @Turing85 System.out.println( String[].class );class [Ljava.lang.String; 怎么样?或者你的详细意思是什么?
      • 我的意思是有一个“类”用于暴露给我们的数组。
      • @Turing85 是的,但不是java.lang.Array。不清楚我在上下文“没有java.lang.Array(暴露给我们)”中的意思吗?
      • java.lang.Array 类不适用于 Java 中的对象层次结构。推理:class-instances 用于检查赋值兼容性,java.lang.Array 丢失了包含类型的信息。此外,泛型不会真正起作用,因为数组是协变的,而泛型是不变的。因此,使用语法 Object[].class, String[].class, .... 似乎是表示数组类的有效方式。
      【解决方案5】:

      类 Object 是所有其他类的超类

      Java 中的所有类都扩展了 Object。类名实际上是 Object(专有名称大写)。这就是为什么所有的类都有toString()和hashCode()方法的原因,因为它们都继承自Object.class

      对象是类实例或数组。

      对象(小写,不是专有名称)是由 new 关键字生成的实例。即: File 是一个类,当您调用 new File() 时,您只是创建了一个 File 对象。老实说,我认为他们应该将其称为类实例。 (澄清:我希望他们永远不会将实例称为对象)

      数组 [...] 可以分配给 Object 类型的变量

      Object[] 是一个数组,可以包含 Object 类型的实例。

      Object[] obj = new Object[100];
      

      obj instanceof Object 计算结果为真。

      【讨论】:

      • "...文件是一个对象..." - 我怀疑你的意思是File?那不是一个对象,而是一个类(在其他一些语言中,这可能被称为 type)。 ---“Object[] 是一个可以包含 Object 类型的实例的数组。” - 我看不出这条语句的相关性。问题。
      • 是的。我一直在校对这个。甚至为这些东西写一个澄清就像在玩积木和魔方一样。
      • 但是,如果一个数组包含了Object(因为它可以赋值给它),并且一个Object是一个类实例,那么数组怎么可能不是一个类实例呢?我不是在说数组可以包含 Object 的实例这一事实,我指的是数组不仅是对象,也是 Object 的实例。
      • Object[] 不是数组。它是一个type(一个变量可以保存一个Objects数组的引用)。
      猜你喜欢
      • 2023-03-08
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多