`

java中的数组与动态数组

    博客分类:
  • Java
阅读更多
int[] x1 = new int[100];
int[] x2;
x2 = new int[100];

int[] x3 = new int[] { 1, 2, 3 };
int[][] x4;
x4 = new int[2][];
x4[0] = new int[1];
x4[1] = new int[2];

int x5[][] = new int[1][];
//会报NullPointerException,因为在定义时没未初始化,所以指向null
//System.out.println(x5[0].length);
int x6[][] = new int[][] { { 1 }, { 2, 3 } };

int x7[][] = { { 1 }, {} };
//可以重新定义某维数组
x7[1] = new int[] { 2, 3, };
//会报ArrayIndexOutOfBoundsException,因为一但某维大小定义完成
//后,是不再改变的,除非再次定义x7,让其指向另外的数组。
x7[2] = new int[] { 2 };

1、数组是对象,继承自Object,因为new Object[0].getClass().getSuperClass()是Object.class,唯一比Object多一个成员变量length,而且应该是public的。
2、java.lang.reflect.Array是final的,所以数组肯定不是它的子类,这个类用来动态生成数组或者操作数组(获得长度等)。
3、java.util.Arrays是一个数组操作应用类,主要就是排序,填充,而分查找等。注意:排序使用的是快速排序,时间复杂度是o(n*log(2^n)),如果你要对数组排序Arrays绝对是首选。
4、数组没有对应的类文件,String对应String.class,但是数组却没有,而且他们的类名字很古怪,可以这样获得 new int[2].getClass().getName(); 这是和其他对象最大的不同点,因为数组类是在运行时生成的。

---------------------------------------------------------------------------------
可以通过以下方法得到MyClass[]的Class实例:arr.getClass()或MyClass[].class。这样,我就可以向数组类里面“窥探”了。
Class clazz = MyClass[].class;
System.out.println(clazz.getConstructors().length);
打印出来的结果是0;证明数组类确实没有构造方法。

如果强行执行clazz.newInstance();就会得到下面的错误。
java.lang.InstantiationException: [Larraytest.MyClass;
证明数组类不能够通过普通的反射方式来创建一个实例。

再看看数组类的“庐山真面目”:
System.out.println(clazz);
输出是:
[Larraytest.MyClass
System.out.println(int[].class.getName());//[I
System.out.println(int[][].class.getName());//[[I

对Java Class文件结构稍有了结就知道,这个字符串的意思就是一个元素类型为arraytest.MyClass的一维数组。也就是说,数组类型不是和普通类 一样,以一个全限定路径名+类名来作为自己的唯一标示的,而数组的 class 串是以 [ 加上一个或者多个L 再加上数组元素类全限定路径再加上类名来做为唯一标示的。

数组的Class类实例是java虚拟机动态创建动态加载的,其结构与普通java类的Class实例有一些不同。

对于数组的Class类实例,还有一些奇怪的现象:
在运行代码 java.lang.reflect.Field fieldarr = clazz.getField("length");的时候,会抛出异常:java.lang.NoSuchFieldException: length,这似乎在说数组类没有length这个域,而这个域其实是我们用的最多的一个(也就是说这个域是肯定存在的)。

java数组最多只能是255维的。

---------------------------------------------------------------------------------

我 们要区分类型和类。可以很肯定的说数组是一种类型,但是它绝不是类。类型是编译器相关的概念,其抽象性跟面向对象无关。类是面向对象中的一个概念。他们不 再同一个级别。int,byte都是类型,都对应相对的Class,系统也提供了对应的装箱类。但是要注意的是,对于他们的底层实现和操作都是 native的,跟面向对象无关,我们可以认为是“内置对象”,他们是用c来实现的,反射和Proxy也是这样的。所以可以取到Class的是任何类型, 而不是类,这个Class类的本身的操作也都是native的,从这个意义上Object类本身也不是一个纯面向对象意义的类。在这个方面,我们可以说: 看起来数组不是一个类。
在语法和实现方式上,数组不像一个类。在虚拟机规范和底层实现,数组是一个像类的对象。

---------------------------------------------------------------------------------
在Java 中,数组是一种完全意义上的对象,他和对象一样保存在堆中、有一个指向Class类实例的引用。所有同一维度和类型的数组拥有同样的Class,数组的长 度不做考虑。对应Class的名字表示为维度和类型。比如一个整型数据的Class为“[I”,字节型三维数组Class名为“[[[B”,两维对象数据 Class名为“[[Ljava.lang.Object”。

---------------------------------------------------------------------------------
动态创建数组的步骤如下:
1、创建Class对象,通过forName(String)方法指定数组元素的类型。
2、调用Array.newInstance(Class, length_of_array)动态创建数组。

访问动态数组元素的方法和通常有所不同,它的格式如下所示,注意该方法返回的是一个Object对象:Array.get(arrayObject, index) 。

为动态数组元素赋值的方法也和通常的不同,它的格式如下所示, 注意最后的一个参数必须是Object类型:Array.set(arrayObject, index, object)。

动态数组Array不单可以创建一维数组,还可以创建多维数组。步骤如下:
1、定义一个整形数组:例如int[] dims= new int{5, 10, 15};指定一个三维数组
2、调用Array.newInstance(Class, dims);创建指定维数的数组

访问多维动态数组的方法和访问一维数组的方式没有什么大的不同,只不过要分多次来获取,每次取出的都是一个Object,直至最后一次,赋值也一样。

动态数组Array可以转化为普通的数组,例如:
Array arry = Array.newInstance(Integer.TYPE,5);
int arrayCast[] = (int[])array;

//----动态创建一维数组
Class<?> classType = Class.forName("java.lang.String");
// 创建一个长度为10的字符串数组
Object array = Array.newInstance(classType, 10);
// 把索引位置为5的元素设为"hello"
Array.set(array, 5, "hello");
// 获得索引位置为5的元素的值
String s = (String) Array.get(array, 5);

//----动态创建多维数组
int[] dims = new int[] { 5, 10, 15 };
// 创建一个具有指定的组件类型和维度的新数组。
Object array = Array.newInstance(Integer.TYPE, dims);
System.out.println(array.getClass().getName());//[[[I
//getLength用来获取数组的长度,第3维数组的长度为5
System.out.println(Array.getLength(array));//5
// 取出三维数组的第3行,为一个数组
Object arrayObj = Array.get(array, 3);
System.out.println(arrayObj.getClass().getName());//[[I
// getComponentType:返回表示数组元素类型的Class,如果此类不是数组类,则此方法返回null
Class<?> cls = arrayObj.getClass().getComponentType();
System.out.println(cls.getName());//[I
// 取出第3行的第5列,为一个数组
arrayObj = Array.get(arrayObj, 5);
// 访问第3行第5列的第10个元素,为其赋值37
Array.setInt(arrayObj, 10, 37);
// 读取第3行第5列的第10个元素
System.out.println(Array.getInt(arrayObj, 10));//37
// 动态数组和普通数组的转换:强行转换成对等的数组
int arrayCast[][][] = (int[][][]) array;
System.out.println(arrayCast[3][5][10]);//37

 

---------------------------------------------------------------------------------

数组转型

 

//----A是B的父类
/*
 * 下面编译就通不过,虽然short可以向上转型成int,但short并非int的子类
 * 因为基本类型根据就不是类,而只是一种类型罢了
 */
//int[] intArr = new short[0];
/*
 * 下面编译可以通过,因为B是A的子类,而不光只是一种类型,还是一种类
 */
A[] aArr = new B[1];
B[] bArr = (B[]) aArr;//编译运行都没有问题
aArr = new A[1];
//	bArr = (B[]) new A[1];//类型转换错误
Object[] oArr = new A[1];
System.out.println(oArr.getClass().getName());//[LA;
//数组也是一个对象
Object o = new A[1];
//虽然使用一个Object引用接收了一个数组对象,但数组本身类型没有丢失
System.out.println(o.getClass().getName());//[LA;
aArr = (A[]) o;//这里还是没有问题,因为o本身是A类型数组
分享到:
评论
1 楼 xiaoyao3857 2011-09-06  
嗯,谢谢,给了我想法!

相关推荐

    用Java动态数组扩充实现线性表

    在Java中,ArrayList类就是动态数组的一个典型例子。当我们创建一个ArrayList时,并不立即分配所有所需的空间,而是先分配一个初始容量,随着元素的增加,当容量不足时,会自动进行扩容操作。 线性表的动态扩充实现...

    45.java数组动态初始化.zip

    45.java数组动态初始化.zip45.java数组动态初始化.zip45.java数组动态初始化.zip45.java数组动态初始化.zip45.java数组动态初始化.zip45.java数组动态初始化.zip45.java数组动态初始化.zip45.java数组动态初始化.zip...

    5-Java数组与方法

    在"7-数组与方法(上)"和"8-数组与方法(下)"的文件中,可能详细讲解了数组的使用方法,包括如何定义、初始化、遍历、修改、查找、排序二维数组,以及如何将数组作为方法参数等实践技巧。通过学习这些内容,开发者能够...

    51.java二维数组动态初始化.zip

    51.java二维数组动态初始化.zip51.java二维数组动态初始化.zip51.java二维数组动态初始化.zip51.java二维数组动态初始化.zip51.java二维数组动态初始化.zip51.java二维数组动态初始化.zip51.java二维数组动态初始化....

    Java中数组的各种应用

    七、数组与集合的转换 Java集合框架如ArrayList和LinkedList可以方便地与数组进行转换。例如,将数组转换为ArrayList: ```java List&lt;Integer&gt; list = new ArrayList(Arrays.asList(numbers)); ``` 八、数组作为...

    Java数组练习题(带答案).doc

    Java数组是Java编程语言中的基本数据结构之一,用于存储固定数量的同类型元素。了解和熟练掌握数组的使用是学习Java的重要环节。本篇练习题涵盖了数组的基本概念、操作和异常处理,下面是针对题目中涉及知识点的详细...

    java 动态数组的体现

    在Java编程语言中,动态数组是一种能够自动调整其大小的数组,它允许我们在程序运行时增加或减少数组容量。这种特性使得动态数组成为处理不确定数量数据的高效工具。本篇文章将深入探讨Java中的动态数组实现,主要...

    Java数组与内存控制

    ### Java数组与内存控制 #### 一、Java数组在内存分配方面的知识 ##### 1.1 数组初始化 - **声明数组的时候如何分配内存:** - 在Java中,数组的声明并不直接分配内存,而仅仅是创建了一个数组引用变量。例如: ...

    java动态数组的应用

    动态数组与静态数组相比最大的特点是其大小可以在运行时改变。在Java中,原始数组是固定长度的,一旦声明后就无法改变其大小。而动态数组则可以通过特定的数据结构或类(如`ArrayList`)来实现。 #### 二、Java动态...

    Java统计数组中相同元素个数

    写的Java文件中实现了统计数组中相同元素个数的功能以及统计数组中小于某个元素的所有元素的数量功能,非常的实用。

    47.java求数组中元素的最大值.zip

    47.java求数组中元素的最大值.zip47.java求数组中元素的最大值.zip47.java求数组中元素的最大值.zip47.java求数组中元素的最大值.zip47.java求数组中元素的最大值.zip47.java求数组中元素的最大值.zip47.java求数组...

    同步java之数组与队列

    本文将深入探讨这两个概念,并结合给定的`Array.java`文件,分析其可能包含的Java数组和队列的实现。 首先,数组是最基本的数据结构之一,它允许存储固定数量相同类型的数据。在Java中,数组通过`[]`符号定义,例如...

    java-对象数组转换为json

    在IT领域,特别是Java编程中,对象数组与JSON之间的转换是一项常见且重要的操作。下面将深入探讨如何在Java中实现对象数组向JSON的转换,并反过来将JSON字符串转换为Java对象数组,同时也会提及一些相关技术和代码...

    java中数组的介绍

    java数组的介绍以及怎么用,用在什么地方

    java中字节数组拼接

    使用链式编程写法实现Java中byte数组的拼接。例如byte[] bytes = ByteUtils.get().add(0x41).add(07).add(11).add("15288930000").add(0x45).toArray();更灵活用法请参考Mybytes

    java螺旋数组代码

    本节将详细介绍如何在Java中实现螺旋数组的功能,包括初始化数组、填充螺旋数组以及打印螺旋数组的过程。 ##### 1. 类与方法定义 首先定义一个名为`RotateArray`的类,并在其中定义`main`方法作为程序入口。此外,...

    java实验数组和集合

    本实验中我们学习了 Java 语言中的数组和集合操作,掌握了 Java 中的数组声明、初始化、索引访问、遍历等操作,并使用冒泡排序算法将数组元素排序。同时,我们还学习了 Java 中的输入输出操作和异常处理。

    json转对象数组与对象数组转json --Java

    ### JSON转对象数组与对象数组转JSON(Java) 在Java编程语言中,处理JSON数据时经常需要进行JSON字符串与Java对象之间的转换。特别是在涉及到数组或集合的场景下,这种转换显得尤为重要。本文将详细介绍如何使用...

    Java数组版ATM

    在Java编程中,"Java数组版ATM"项目是一个典型的面向对象设计实例,它通过数组来模拟自动取款机(ATM)的功能。这个项目旨在教授如何利用Java语言中的类、对象、数组以及相关的面向对象设计原则来实现一个简单的银行...

Global site tag (gtag.js) - Google Analytics