https://blog.csdn.net/weixin_43593990/article/details/100500538
数组有哪些奇怪的地方?
1)数组没有类
2)数组没有任何实例方法。添加的话直接就是 arr[1] = “123”;
3)数组的构造方法更愿意称之为创建对象的命令,而不是方法。
数组的存在说明了什么?
对象的创建可以不是根据class文件;
即使数组对象没有任何属性与方法,但数组有特殊形式的属性与方法,侧面证明了对象只是对属性与方法封装。
数组是对象依然存放在堆中。因为他是有内存地址的。其实数组还集成了Object,只不过我们不能在API查看到。
数组是什么?
不管在其他语言中是什么,数组在Java中可得看作一个对象,它有一些值得探讨的特性。
Java中的数组其实是一个对象,但是确实是一个特殊的对象,实在是太特殊了,以致我们都不好把它多做对象处理。
java绝大部分是面向对象的语言,数组也是一个对象。
首先我们看一下表面现象,数组创建的时候采用的是如下语句:
MyClass[] arr = new MyClass[9];
而普通类采用的是如下语句:
MyClass obj = new MyClass();
就是说,创建数组的时候不使用小括号传参。使得数组和普通类看起来就有很多不同,因为小括号里的参数是传递给构造方法的,进而让人感觉数组类是没有构造方法的。
数组是对象的依据
数组的父类是Object,
new Object[0].getClass().getSuperClass() 是Object.class
数组没有对应的类文件,String对应String.class.数组却没有,而且他们的 类名字很古怪,可以这样获得 new int[2].getClass().getName();
这是和其他对象最大的不同点,因为数组类是在运行时生成的。
java.lang.reflect.Array是final的,所以数组肯定不是它的子类,这个类用来动态生成数组或者操作数组(获得长度等)
再往深了想,还有很多让人感觉不自然的东西。可以肯定的是,java确实将数组作为了一个类来处理。还是用上面的例子说明:
可以通过以下方法得到MyClass[]的Class实例:arr.getClass()或MyClass[].class。这样,我就可以向数组类里面“窥探”了。
Class clazz = MyClass[].class;
System.out.println(clazz.getConstructors().length);
打印出来的结果是0;证明数组类确实没有构造方法。
数组类的“庐山真面目”:
System.out.println(clazz);
输出是:
[Larraytest.MyClass
对Java Class文件结构稍有了解就知道,这个字符串的意思就是一个元素类型为arraytest.MyClass的一维数组。也就是说,数组类型不是和普通类一样,以一个全限定路径名+类名来作为自己的唯一标示的,而是以[+一个或者多个L+数组元素类全限定路径+类来最为唯一标示的。这个()也是数组和普通类的区别。而这个区别似乎在某种程度上说明数组和普通java类在实现上有很大区别。因为java虚拟机(java指令集)在处理数组类和普通类的时候,肯定会做出区分。我猜想,可能会有专门的java虚拟机指令来处理数组。
分析到这里,基本上可以肯定:java对数组对象化的操作的支持是指令级的,也就是说java虚拟机有专门针对数组的指令。数组的Class类实例是java虚拟机动态创建动态加载的,其结构与普通java类的Class实例有一些不同。
java中的数组作为对象能带来什么好处
1)越界检查
2)length field:与传统的C++中的数组相比,length字段可以方便的得到数组的大小;但要注意,仅仅可以得到数组的大小,不能得到数组中实际包含多少个元素,因为length 只会告诉我们最多可将多少元素置入那个数组。
3) 初始化:对象数组在创建之初会自动初始化成null,由原始数据类型构成的数组会自动初始化成零(针对数值类型),(Char)0 (针对字符类型)或者false (针对布尔类型)。
4) 数组作为返回值:首先,既然数组是对象,那么就可以把这个对象作为返回值;而且,不必担心那个数组的是否可用只要需要它就会自动存在而且垃圾收集器会在我们完成后自动将其清除