黑马程序员技术交流社区

标题: 【哈尔滨校区](崔喆轩)反射理解 [打印本页]

作者: 崔喆轩    时间: 2016-2-21 23:01
标题: 【哈尔滨校区](崔喆轩)反射理解
六、数组的反射
1、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。数组字节码的名字:有[和数组对应类型的缩写,如int[]数组的名称为:[I
2、Object[]与String[]没有父子关系,Object与String有父子关系,所以new Object[]{“aaa”,”bb”}不能强制转换成new String[]{“aaa”,”bb”}; Object x =“abc”能强制转换成String x =“abc”。
3、如何得到某个数组中的某个元素的类型,
        例:
              int a = new int[3];Object[] obj=new Object[]{”ABC”,1};
        无法得到某个数组的具体类型,只能得到其中某个元素的类型,
        如:
               Obj[0].getClass().getName()得到的是java.lang.String。
4、Array工具类用于完成对数组的反射操作。
        Array.getLength(Object obj);//获取数组的长度
        Array.get(Object obj,int x);//获取数组中的元素
5、基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
示例:
[java] view plaincopy
1. package cn.itheima.Demo;  
2.   
3. import java.lang.reflect.Array;  
4. import java.util.Arrays;  
5.   
6. public class ArrayReflect {  
7.     public static void main(String[] args) {  
8.         int [] a1 = new int[]{1,2,3};  
9.         int [] a2 = new int[4];  
10.         int[][] a3 = new int[2][3];  
11.         String [] a4 = new String[]{"a","b","c"};  
12.         System.out.println(a1.getClass().equals(a2.getClass()));//true  
13.     System.out.println(a1.getClass().equals(a3.getClass()));//false  
14.     System.out.println(a1.getClass().equals(a4.getClass()));//false  
15.     System.out.println(a1.getClass().getName());//[I  
16.     System.out.println(a4.getClass().getName());//[Ljava.lang.String;  
17.     System.out.println(a1.getClass().getSuperclass());//class java.lang.Object  
18.     System.out.println(a4.getClass().getSuperclass());//class java.lang.Object  
19.           
20.         Object obj1=a1;  
21.         Object obj2=a3;  
22.         Object obj3=a4;  
23.           
24. //      Object[] obj11=a1;//这样是不行的,因为a1中的元素是int类型,基本数据类型不是Object  
25.         Object[] obj13=a3;  
26.         Object[] obj14=a4;//这样可以,因为String数组中的元素属于Object  
27.           
28.         System.out.println(a1);//[I@4caaf64e  
29.         System.out.println(a4);//[Ljava.lang.String;@6c10a234  
30.         System.out.println(Arrays.asList(a1));//[I@4caaf64e  
31.         System.out.println(Arrays.asList(a4));//[a, b, c]  
32.           
33.         /* Arrays.asList()方法处理int[]和String[]时的差异。
34.          * 打印Arrays.asList(a1);还是跟直接打印a1是一样的
35.             打印Arrays.asList(a4);就会把a3的元素打印出来。
36.             这是因为此方法在JDK1.4版本中,接收的Object类型的数组,
37.             而a3可以作为Object数组传入。但是a1不可以作为Object数组传入,所以只能按照JDK1.5版本来处理。
38.             在JDK1.5版本中,传入的是一个可变参数,所以a1就被当作是一个object,也就是一个参数,
39.             而不是数组传入,所以打印的结果还是跟直接打印a1一样。
40.          */  
41.           
42.         //Array工具类用于完成对数组的反射操作。如打印任意数值  
43.         printObject(a1);  
44.         printObject(a4);  
45.         printObject("abc");  
46.           
47.     }  
48.     //打印任意数值  
49.     private static void printObject(Object obj) {  
50.         Class clazz=obj.getClass();  
51.         //如果传入的是数组,则遍历  
52.         if(clazz.isArray()){  
53.             int len =Array.getLength(obj);//Array工具类获取数组长度方法  
54.             for(int x=0;x<len;x++){  
55.                 System.out.println(Array.get(obj, x));//Array工具获取数组元素  
56.             }  
57.         }  
58.         else  
59.             System.out.println(obj);  
60.     }  
61. }  
七、HashCode的分析
        覆写hashCode()方法的意义:只有存入的是具有hashCode算法的集合的,覆写hashCode()方法才有价值。
1、哈希算法的由来:
        若在一个集合中查找是否含有某个对象,通常是一个个的去比较,找到后还要进行equals的比较,对象特别多时,效率很低。有这么一种HashCode算法,有一个集合,把这个集合分成若干个区域,每个存进来的对象,可以算出一个hashCode值,根据算出来的值,就放到相应的区域中去。当要查找某一个对象,只要算出这个对象的hashCode值,看属于第几个区域,然后到相应的区域中去寻找,看是否有与此对象相等的对象。这样查找的性能就提高了。
示意图:                                
2、要想HashCode方法有价值的话,前提是对象存入的是hash算法这种类型的集合当中才有价值。如果不存入是hashCode算法的集合中,则不用复写此方法。
3、如果没有复写hashCode方法,对象的hashCode值是按照内存地址进行计算的。这样即使两个对象的内容是想等的,但是存入集合中的内存地址值不同,导致hashCode值也不同,被存入的区域也不同。所以两个内容相等的对象,就可以存入集合中。
        所以就有这样的说法:如果两个对象equals相等的话,你应该让他们的hashCode也相等。如果对象存入的不是根据hash算法的集合中,就不需要复写hashCode方法。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2