反射----6
数组的数据类型 数组数据类型的父类
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1. 数组的数据类型
(1). 数组的类型
[1], Java规定:具有相同维数【1】和元素类型【2】的数组具有相同的数组类型
【注意】
数组之间要想整体的数据类型相同,必须满足两个相同:维数相同+元素类型相同
【举例1】
int[] a1 =new int[3];
int[] a2 =new int[4];
int[][] a3 =new int[2][3];
String[] a4 =new String[3];
System.out.println("a1.getClass()==a2.getClass():"+ (a1.getClass() ==a2.getClass()));
System.out.println(a1.getClass().getName());
System.out.println(a4.getClass().getName());
打印结果:
a1==a2:false
a1.getClass()==a2.getClass():true
[I
[Ljava.lang.String;
【分析】
a1的数组类型是 一维+ int型的数组,a2的数组类型是 一维+ int型的数组
维数相同,数组元素类型相同,所以a1和a2一定是类型相同的数组类。由于字节码一定是唯一的并且字节码文件就代表这个类,所以getClass()获取的字节码文件对象都是一个,所以地址一样。因此“==” 返回true
【举例2】
System.out.println("a1.getClass()==a4.getClass():"+ (a1.getClass() ==a4.getClass()));
System.out.println("a1.getClass()==a2.getClass():"+(a1.getClass() ==a3.getClass()));
编译无法通过 如图
【分析】
错误提示信息:a1.getClass() 返回的Class类型是Class<? extends int[]>,泛型信息是int[]的子类,但是a4.getClass()返回的是Class类型是Class<? extends String[]>。
【JDK6新特性】
对于数组类型的变量,编译器在编译时,其实已经知道类型了。也就是说,编译器认为这2个类型是不一样的。根本没有比较的需要。对于总是不成立的比较,其实是没有意义的。所以编译直接不通过。
2. 数组类型的父类
(1). 数组元素的直接父类
任意维度,任意元素类型的数组的直接父类只有一个:java.lang.Object
【举例】
//a1: new int[3]
System.out.println(a1.getClass().getSuperclass().getName());
//a2: new int[4]
System.out.println(a2.getClass().getSuperclass().getName());
//a3: new int[2][3]
System.out.println(a3.getClass().getSuperclass().getName());
//a4: new String[4]
System.out.println(a4.getClass().getSuperclass().getName());
打印结果:
java.lang.Object
java.lang.Object
java.lang.Object
java.lang.Object
(2).数组类型和Object类之间的多态转换
[1]. 基本数据类型的一维数组可以当做Object类型使用,但是不能当做Object[]类型使用。
不能当做Object[]的原因:基本数据类型本身不属于引用数据类型,所以没有办法实现多态。
[2]. 非基本数据类型的任意维数组和基本数据类型的高维数组既可以当做Object类型使用,又可以当做Object[]类型使用。
{1}. 基本数据类型的高维数组可以做到上述两点的原因是:高维数组是数组的数组。元素本身是数组,可以当做Object类型使用。又被包装成多一维数组,所以可以当做Object[]使用。
{2}. 以非基本数据类型的一维数组为例,可以看成Object[]的原因就是非基本数据类型数组的元素是引用类型,一定是Object的子类,所以元素类型可以传给Object。同时又是数组,所以,可以看做Object[]。
{3}. 非基本数据类型的任意维数组和基本数据类型的高维数组 满足:无论是什么类型元素的任意维度的数组的直接父类都是Object,所以又可以当做Object类使用。
【结论汇总---反串】
{1}. 任意元素数据类型+任意维度都是Object类的子类。即:任何类型的数组,只要是数组就是Object类型的子类。
{2}. 一维基本数据类型数组以外的所有数组都又是Object[]的子类
【技巧】记住以上两条结论最重要
【练习】
int[] a1 =new int[3];
int[] a2 =new int[4];
int[][] a3 =new int[2][3];
String[] a4 =new String[3];
Object aObj1 =a1;
Object aObj2 =a4;
Object[] aObj3 =a1;
Object[] aObj4 =a3;
Object[] aObj5 =a4;
问:编译能通过么?为什么?
{1}. Object aObj1 =a1; //编译可以通过
{2}. Object aObj2 =a4; //编译可以通过
{1}和{2}编译正确的原因:任意类型的数组都是Object的子类。
{3}. Object[] aObj3=a1; //编译失败
因为一维基本数据类型数组仅是Object的子类,和Object[]没有必然的联系
{4}. Object[] aObj4 =a3; //编译正确
{5}. Object[] aObj5=a4; //编译正确
{4}和{5}编译正确的原因:一维基本类型数组以外的所有数组又都是Object[]的子类,所以编译正确。
(3). 集合 + 元素 VS 数组 + 元素多态性的区别
[1]. 多态性的规律
数据类型多态性规律:只要不在<>中的数据类型,一律可以有多态传递
[2]. <>中的数据类型不具有多态性的原因
<>中的数据类型,由于仅仅是泛型,仅仅供Javac使用,编译完会被擦除,所以不具备多态性
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------