java 数组知道少?

 

package com.easyway.commons.ispace.dev.oop.grammers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
 * 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(); 这是和其他对象最大的不同点,因为数组类
 * 是在运行时生成的。

 * @author longgangbai
 * @date 2010-5-19
 * @version 1.0
 * @since JDK6.0
 */
public class JavaArray {

	public static void main(String[] args) {
		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 };
		
		System.out.println(x7[1].length);
		
		List<String> strList=new ArrayList<String>();
		for (int i = 0; i < 1000; i++) {
			strList.add("sdf"+Math.round(i));
		}
		
		Arrays.sort(strList.toArray(new String[strList.size()]));
		Collections.sort(strList);
		
		System.out.println(x4.getClass().getName()); //[[I
		
		
		
		Class clazz = x7.getClass();
		System.out.println(clazz.getConstructors().length);//打印出来的结果是0;证明数组类确实没有构造方法。

       //java.lang.NoSuchFieldException: length
		try {
			java.lang.reflect.Field fieldarr = clazz.getField("length");
		} catch (SecurityException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (NoSuchFieldException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		try {
			System.out.println(x4.getClass().newInstance()); //java.lang.InstantiationException:
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} //[[I
	}
}

 

 

 

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”。

你可能感兴趣的:(java,数据结构,虚拟机,oop)