【问题标题】:Why isn't there a java.lang.Array class? If a java array is an Object, shouldn't it extend Object?为什么没有 java.lang.Array 类?如果一个java数组是一个对象,它不应该扩展对象吗?
【发布时间】:2012-01-22 16:59:18
【问题描述】:

这里是 java 包树: http://docs.oracle.com/javase/7/docs/api/java/lang/package-tree.html

我阅读了一篇关于 Java 的教程,其中指出在 Java 中数组是对象。

数组类在哪里?为什么我们可以制作这样的数组:

byte[] byteArr = new byte[];
char[] charArr = new char[];
int[] intArr = new int[];

并且数组将继承 Object 的方法;例如:

    byte thisByte = 1;
    byte thatByte = 2;
    byte[] theseBytes = new byte[] {thisByte, thatByte};
    int inheritance = theseBytes.length; //inherited 'length' field and some methods
    int wasntInWill = thatByte.length; //error

这是怎么回事?

编辑:

根据答案,我现在知道它是java.lang.reflect 包中的final 类。

我现在已经在我的 Android 项目中创建了一个包 java.lang.reflect,并向其中添加了一个名为 Array.java 的类。为了确认这是在原始类中的方式,Eclipse 给了我错误“...已经存在于 path/to/android.jar”

如果我写出与java.lang.reflect.Array 相同的类,但更改toString() 方法...这应该在我的应用程序中工作,对吧?

【问题讨论】:

  • 数组是对象,但构造语法与通常的 java 对象略有不同
  • 错了。它不是“java.lang.reflect 包中的final 类”。

标签: java arrays object


【解决方案1】:

来自JLS

每个数组都有一个关联的 Class 对象,与所有其他对象共享 具有相同组件类型的数组。 [This] 就像:数组的直接超类 type 是 Object [and] 每个数组类型都实现了 Cloneable 接口 和 java.io.Serializable。

以下示例代码显示了这一点:

class Test {
    public static void main(String[] args) {
        int[] ia = new int[3];
        System.out.println(ia.getClass());
        System.out.println(ia.getClass().getSuperclass());
    }
}

哪个打印:

class [I
class java.lang.Object

其中字符串"[I" 是类对象"array with component type int" 的运行时类型签名。

是的,由于数组类型有效地扩展了 Object,您可以在 arrayObject 上调用 toString() 也可以参见上面的示例

int arr[] = new arr[2];
arr.toString();

【讨论】:

  • 您好,感谢您的信息。我编辑了我的问题以得到我真正想要的 - 如何覆盖数组的 toString() 方法。
  • 不客气,你手里没有要改的类,最好创建一个接受数组对象的util方法并以你想要的形式打印出来
  • 我知道我只是想看看能不能做到。当然,在我问这个问题之前我应该​​先试一试,但是我有一个小菜鸟担心它会炸毁我的电脑!
  • 对于 toString() 只需使用 Arryas.asList()
  • 我也知道这一点,但谢谢。我想看看是否可以通过编写 toString() 方法使其正常用于我的数组。
【解决方案2】:

数组是一种语言特性——它们具有用于声明和访问的特定语法。而且他们的类定义对你是隐藏的。

它们在反射 API 中有一个表示形式 - java.lang.reflect.Array

顺便说一句,length 字段不是从Object 继承的。继承.getClass().toString()等方法。

【讨论】:

  • 哦,那么 java.lang.reflect.Array 是类定义吗?是的,我的意思是从某个数组对象继承(以证明某处有一个数组类)
  • length 字段不存在,任何数组中都没有这样的字段。它只是代表ARRAYLENGTH 类似字段的操作码的Java 语言功能。从技术上讲,几乎每个 impl。但是,在对象头中有这样的字段。数组也实现了 2 个接口:SerializableClonable 并发布 clone() 方法。
  • @Ozzy 不,java.lang.reflect.Array 不是类定义。它是一个实用反射类,只有静态方法。
  • @Bozho 有计划解决这个问题吗?你已经有 4.5 年了。
  • 只是为了让后面的人更清楚。如果你做Integer[] array = new Integer[0]; System.out.println(array.getClass());,你应该看到类是class [Ljava.lang.String;,而不是java.lang.reflect.Array
【解决方案3】:

为什么没有数组类?

个数组类,程序中使用的每种元素类型一个。 JLS 和 JVM Spec 都明确指出,数组的类对象是动态创建的。 JLS #10.8 'Class Objects for Arrays'JVM Spec #5.3.3 'Creating Array Classes'

如果一个java数组是一个对象,它不应该扩展Object?

它确实扩展了java.lang.Object. JLS #10.8 明确指出“每个数组类型的直接超类都是 Object。”

【讨论】:

  • 你来晚了,我已经找到课程了(见上面的答案)
  • @Ozzy 您在任何地方都找不到课程。它没有在任何地方定义。它甚至不是一个班级。每种原始类型都有一个,例如int[],每个对象类型都有一个,例如Object[],String[],
  • @user207421 在 JLS 10.8 中说“数组类型不是类”。那么是动态创建的类,而不是类?
【解决方案4】:

对上述代码段稍加阐述:

public class ClassForName {
    public static void main(String[] argv) throws ClassNotFoundException {
        Class theClass = Class.forName("[I");
        System.out.println(theClass.getName());
        Class superClass = theClass.getSuperclass();
        System.out.println(superClass.getName());
    }
}

结果:

C:\JavaTools>java ClassForName
[I
java.lang.Object

可以看出,“[I”是类的名称,用英文称为“array of int”。该类是一个“完全公民”的Java 类,它响应Object 的所有方法。唯一不同的是new语法不同,不支持Class的newInstance()方法。

(类“[I”、“[C”等,在 JVM 中是“预定义的”——没有与它们对应的 .class 文件。Java 也会在运行中隐式创建,如果您的程序中有一个“MyJavaClass”数组,则为“[MyJavaClass;”类。)

【讨论】:

  • 大部分是正确的,但是: 1. 进一步的区别是类是CloneableSerializable。 2.JLSJVM Specification 都声明all 数组类是动态创建的。没有关于其中一些是内置的。
猜你喜欢
  • 2011-05-25
  • 2011-05-07
  • 2021-08-22
  • 1970-01-01
  • 2023-01-04
  • 2023-03-11
  • 2022-01-15
相关资源
最近更新 更多