为啥没有 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 个接口:Serializable
和 Clonable
并发布 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. 进一步的区别是类是Cloneable
和Serializable
。 2.JLS 和JVM Specification 都声明all 数组类是动态创建的。没有关于其中一些是内置的。以上是关于为啥没有 java.lang.Array 类?如果一个java数组是一个对象,它不应该扩展对象吗?的主要内容,如果未能解决你的问题,请参考以下文章