Java数组类型
来源:互联网 发布:香港恐怖在线知乎 编辑:程序博客网 时间:2024/06/11 10:43
在Java中,数组可以说是经常用到的,但关于数组是什么类型的这个问题,我却没有深入研究过。以下内容参考自《Java语言规范》,记录了数组的类型是什么?更进一步地说,数组对象的getClass()返回的是什么?
1.数组更详细的特点
数组具有以下几点特点:
a.在Java编程语言中,数组是动态创建的对象,可以被赋值给Object类型的变量。Object类的所有方法都可以在数组上调用。
b.数组对象包含大量的变量。
c.数组的所有元素都具有相同的类型,称为数组的元素类型。如果数组的元素类型为T,那么数组自身的类型就写作T[ ]。
这里针对数组的特点a进行详细说明:
下面代码片段中,会创建一个数组对象,并且这个对象可以赋值给Object对象。
int[] ai1 = {1,2};//隐式地创建一个新的数组对象int[] ai = new int[2];//显式地创建一个数组对象Object o = ai;//数组对象可以赋值给Object类型的变量o = ai1;
通过上面的代码片段,再联系“数组是动态创建的对象”这句话,我们可以猜测:数组的类型很可能是运行时通过反射动态创建的,并且其类型是Object的子类。
既然知道数组具有特定类型了,那么这个类型具有什么成员呢?下面将进行说明。
2.数组类型的成员
数组类型的成员包括以下所有内容:
- public final 域 length,它包含了数组的元素数量。length可以是正数或0。
- public 方法 clone,它覆盖了Object类中的同名的方法,并且不会抛出任何受检异常。
多维数组的克隆是浅复制,即它只创建单个新数组,子数组是共享的。 - 所有从Object类继承而来的成员,Object中唯一没有被继承的方法就是clone方法。
因此,数组具有与下面的类相同的public域和方法:
class A<T> implements Cloneable,java.io.Serializable { public final int length = X; public T[] clone() { try{ return (T[])super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(e.getMessage()); } }}
注意:在上面例子中,如果数组真的以这种方式实现,那么其中向T[ ]的强制类型转换会产生非受检警告。
从上面可以知道,数组是可克隆的
class Test1 { public static void main(String[] args) { int ia1[] = {1,2}; int ia2[] = ia1.clone(); System.out.print((ia1 == ia2) + " "); ia1[1]++; System.out.println(ia2[1]); }}
这个程序会产生下面的输出:
false 2
该输出展示了ia1和ia2所引用的数组元素是不同的变量。
下面的例子说明多维数组克隆后共享子数组:
class Test2 { public static void main(String[] args) throws Throwable { int ia[][] = { { 1, 2 }, null }; int ja[][] = ia.clone(); System.out.print((ia == ja) + " "); System.out.println(ia[0] == ja[0] && ia[1] == ja[1]); }}
这个程序会产生下面的输出:
false true
该输出展示了 int[ ] 数组 ia[0] 和 int[ ] 数组 ja[0] 是同一个数组。
3.数组的Class对象
每个数组都与一个Class对象关联,并与其他具有相同元素类型的数组共享该对象。尽管数组类型不是类,但是每一个数组的Class对象起到的作用看起来都像是:
- 每个数组类型的直接超类都是Object。
每个数组类型都实现了Cloneable 接口和 java.io.Serializable 接口
下面的代码用于测试上面的特点:
package com.test;class A {}class B extends A implements Comparable<B>{ @Override public int compareTo(B o) { return 0; }}public class Test2 { public static void main(String[] args) throws Throwable { B[] ba = new B[2]; B b = new B(); B[] ba1 = new B[2]; //测试数组的Class对象是共享的 System.out.println(ba == ba1); System.out.println(ba.getClass() == ba1.getClass()); //测试数组ba和b的Class对象是否一样 System.out.println(ba.getClass() + " | " + b.getClass()); //测试数组ba和b的超类是否一样 System.out.println(ba.getClass().getSuperclass() + " | " + b.getClass().getSuperclass()); //测试数组ba和b实现的接口分别是什么 for(Class<?>c : ba.getClass().getInterfaces()) System.out.println("Superinterfaces: " + c); System.out.println("-----------"); for(Class<?>c : b.getClass().getInterfaces()) System.out.println("Superinterfaces: " + c); }}
上面程序输出是:
false
true
class [Lcom.test.B; | class com.test.B
class java.lang.Object | class com.test.A
Superinterfaces: interface java.lang.Cloneable
Superinterfaces: interface java.io.Serializable
- - - - - - - - - - -
Superinterfaces: interface java.lang.Comparable
其中,字符串“[Lcom.test.B”是“元素类型为com.test.B的数组”的Class对象的运行时类型签名。
根据上面的输出结果,可得出以下总结。
数组的Class对象是共享的。
虽然每个数组都与一个 Class 对象关联,但数组的Class对象并不等于数组元素的Class对象。
从上面这个输出可以看出:class [Lcom.test.B; | class com.test.B数组的类型是Object类的子类,并且数组的类型和数组元素的类型不一样。
如上面的输出中, B[ ] 的超类是Object,而B的超类是A。B[ ]类型实现的是Cloneable 和 Serializable 接口,而B类实现的是Comparable 接口。
- Java 数组类型(基本类型数组类型、封装类型数组类型、数组的数组类型)
- java:数组类型
- java 数组类型
- JAVA 数组类型
- Java的数组类型
- Java数组类型
- JAVA 数组类型
- Java数组类型转换
- Java数组类型
- java基本类型、数组和枚举类型
- java,返回多类型数组
- java基本类型数组初始化
- Java中数组的类型
- java 当中引用类型数组
- java基本类型数组初始化
- java基本类型数组初始化
- java基本类型数组初始化
- java基本类型数组初始化
- Flume-NG源码阅读之HDFSEventSink
- 关于主键
- 如何用EasyWebSvr搭建Axure本地访问地址
- firefox中使用ocx的方法 嵌入object标签+js判断各个浏览器的方法
- 什么叫抽象,编程中怎么理解抽象的概念。
- Java数组类型
- android 获取网络类型的方法
- jQuery 插件autocomplete 应用
- Flume环境部署和配置详解及案例大全
- 优先队列详解
- 代码行统计工具
- easyui datagrid editor在编辑状态下更新列值并不结束编辑。
- [Java]将二叉树的左右子树交换 非递归实现
- android之android.intent.category.DEFAULT的用途和使用 隐式Intent