为啥没有 java.lang.Array 类?如果一个java数组是一个对象,它不应该扩展对象吗?

Posted

技术标签:

【中文标题】为啥没有 java.lang.Array 类?如果一个java数组是一个对象,它不应该扩展对象吗?【英文标题】: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 类”。 【参考方案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.JLS 和JVM Specification 都声明all 数组类是动态创建的。没有关于其中一些是内置的。

以上是关于为啥没有 java.lang.Array 类?如果一个java数组是一个对象,它不应该扩展对象吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我没有 NotSerializableException?

为啥我的子类没有继承父类的所有方法?

为啥执行时没有执行基类的构造函数?

为啥工会成员数据没有默认初始化?

为啥 ArrayList 没有标记为 [过时]?

如果没有空格分隔符,为啥 XmlReader 会跳过所有其他元素?