数组是基本上所有语言的一种数据类型,它表示的是一组相同类型的数据的集合,具有固定的长度,在内存中占有连续的空间。本文介绍了一些Java语言中的数据的一些特性。
Java中的数组是对象吗?
Java是一门面向对象的语言。在面向对象的语言中我们可以直接使用标准的类库,也可以使用组合和集成等面向对象的特性来构建自己的类,并且根据自己构建的类来创建对象。那么,问题就来了:在Java语言中,数组是对象么?
要判断数组是不是对象,就要先了解什么是对象,对象的定义是什么。在较高的层面上,对象是根据某个类创建出来的一个实例,表示某类事物中一个具体的个体。对象具有各种属性,并且有一些特定的行为;而在较低的层面上,站在计算机的角度上,对象就是内存中一个内存块,这个内存块中封装了一些数据,也就是定义的各个属性,所以,对象是用来封装数据的。那么我们就来分析下什么是对象,以简单的Person对象为例,它在内存中可以表示为:
图中蓝色矩形表示一个引用或者一个基本的数据类型,多个矩形图就组成了一个对象(P)。
name是一个地址值也就是一个引用,指向了一个存在于堆内存的字符串“张飞”。
由上图可知,对象由多个内存块组成,不同的内存块对应了对象的不同属性。而数组也是由一个个内存块组成的,封装了一些数据,这样也可以把数组称之为对象。
|
|
由此可知,在对于数组a,可以访问它的属性,也可以调用它的方法。数组就具有了Java中对象所具备的特点:封装了一些数据,可以访问属性,也可以调用方法。所以,数据是对象。
Java中数组的类型
Java是一种强类型的语言。如果是对象就必须属于一个类型,比如用Person类创建了一个对象,这个对象的类型就是Person。数组也是一样的:
|
|
运行结果如下:
[I
[Ljava.lang.String;
[[I
所以数组也是有类型的。只是类型比较奇怪。虽然我们没有像创建Person类一样去创建Int或者String类,但是在虚拟机自动创建了数组类型,可以把数组类型和8重基本数据类型一样,当做Java的内建类型。这种类型的命名规则是这样的:
每一维度用一个[表示;开头两个[,就代表是二维数组。[后面是数组中元素的类型(包括基本数据类型和引用数据类型)
在java语言层面上,s是数组,也是一个对象,那么他的类型应该是String[],这样说是合理的。但是在JVM中,他的类型为[java.lang.String。顺便说一句普通的类在JVM里的类型为 包名+类名,也就是全限定名。同一个类型在java语言中和在虚拟机中的表示可能是不一样的。
Java中数组的继承关系
上面验证了数组是对象,那么久可以用操作对象的方式来操作数组。并且在虚拟机中有它特别的类型。在Java中所有类的父类都是Object,所以数组的顶层父类也是object。这就说明数组可以向上直接转型到Object,也可以向下进行强制转换。可以用instanceof判断:
|
|
Java中数组的另一种“继承”关系
先来看一段代码:
String arrStr[] = new String[5];
Object[] objectStr = arrStr;
由此我们可以推测String[]继承自Object[],而Object[]又继承自Object?
System.out.println(objectStr.getClass().getSuperclass().getName());
运行结果是: java.lang.Object
但是根据上述运行结果可知String[]的直接父类是Object而不是Object[],但是Object[]的引用指向了String[]类型的对象。那么关系就有点像这样:
但是这又违背了Java单继承的原则。所以上述假设是错的。也就是说,String[]不继承自Object[],但是我可以允许你向上转型到Object[],这种特性是赋予你的一项特权。
其实这种关系可以这样表述:如果有两个类A和B,如果B继承(extends)了A,那么A[]类型的引用就可以指向B[]类型的对象。