【黑马程序员】java基础加强_反射
2014-06-20 16:15
423 查看
------- android培训、java培训、期待与您交流! ----------
反射,在我看来是一种很强大的技术。
定义:反射就是把java类中的各种成分映射成相应的java类。
也就是说,我们可以用各种方式来进行反射,得到字节码文件,然后可以拿到该字节码文件中其他成员。其方式有很多种
1、类反射。
我们可以通过类或者对象来拿到对应的字节码类。
返回的方式有三种:1)类名.class; 2)对象.getClass; 3)Class.forName("类名");该方法可以查询或者加载对应的字节码
2、构造方法反射。
通过通过泛型指定接收的参数类型,拿到类中构造的方法,再用改构造方法得到其字节码文件。
3、对象反射。
通过建立的对象,并指定可见参数,拿到字节码文件,并获取期中其他成员,private修饰的成员 无法访问,所以 提供一种名为“暴力反射”的方式,强制性让private变为可见,从而拿到这些参数的值。
4、方法反射。
先通过指定参数,来确定需要拿哪些方法,然后通过对象其中的方法来进行反射,拿到字节码方法,在对一个对象进行作用,若方法为静态,则传入的参数为null
5、数组反射。
通过数组,拿到字节码文件,这里需要提到的是,不同的数组类型 所拿到的字节码文件不同。
以上是我所知道的 五种反射方式。
反射还可以arrays工具类结合使用。
这里需要提到的是JDK1.5以及之前的版本的不同,之前的版本Arrays.asList(obj)接受的为Object类型,但是int属于基本类型,它并不在Object之内,在1.5可变参数的功能加入之后接受的类型变为可变参数,但之前的方法并没有废除,所以,当接受的参数类型为int时,直接交给1.5的方法处理,也就造成 整个数组变成一个整体输出,而不是数组。
------- android培训、java培训、期待与您交流! ----------
反射,在我看来是一种很强大的技术。
定义:反射就是把java类中的各种成分映射成相应的java类。
也就是说,我们可以用各种方式来进行反射,得到字节码文件,然后可以拿到该字节码文件中其他成员。其方式有很多种
1、类反射。
我们可以通过类或者对象来拿到对应的字节码类。
返回的方式有三种:1)类名.class; 2)对象.getClass; 3)Class.forName("类名");该方法可以查询或者加载对应的字节码
String str1 = "abc"; Class cls1 = str1.getClass(); Class cls2 = String.class; Class cls3 = Class.forName("java.lang.String"); System.out.println(cls1 == cls2); System.out.println(cls1 == cls3); System.out.println(int.class.isPrimitive());//是否为基本类型true System.out.println(int.class == Integer.class);//是否为同一个字节码文件 false System.out.println(int.class == Integer.TYPE);//所包含的基本类型的字节码 true System.out.println(int[].class.isPrimitive());//是否为基本类型 false 数组不是
2、构造方法反射。
通过通过泛型指定接收的参数类型,拿到类中构造的方法,再用改构造方法得到其字节码文件。
Constructor<String> constructor = String.class.getConstructor(StringBuffer.class);//括号中加入接受的参数,从而指定构造的函数。 String str = constructor.newInstance(new StringBuffer("abc")); System.out.println(str.charAt(0));
3、对象反射。
通过建立的对象,并指定可见参数,拿到字节码文件,并获取期中其他成员,private修饰的成员 无法访问,所以 提供一种名为“暴力反射”的方式,强制性让private变为可见,从而拿到这些参数的值。
ReflectPoint rp1 = new ReflectPoint(1,11); ReflectPoint rp2 = new ReflectPoint(2,22); Field fieldY = rp1.getClass().getField("y"); //getField()只能拿到可见参数。 //如:public Field fieldX = rp1.getClass().getDeclaredField("x"); //getField()能拿到不可见参数。 //如:private fieldX.setAccessible(true);//暴力反射,强制对定义过的变量可见 //作用在字节码上,没有定义在对象上,所以fieldY不等于5,需要从对象上取值 System.out.println(fieldY.get(rp1)); System.out.println(fieldX.get(rp1)); // Field fieldy2 = rp2.getClass().getField("y"); Field fieldx2 = rp2.getClass().getDeclaredField("x"); fieldx2.setAccessible(true); System.out.println(rp2.getClass().getField("y").get(rp2)); System.out.println(fieldx2.get(rp2)); changeStringValue(rp1); System.out.println(rp1);拿单个字段用getField("x"); 而要拿所有字段的时候 则定义一个数组,然后通过getFields();方法循环获得所有字段。
4、方法反射。
先通过指定参数,来确定需要拿哪些方法,然后通过对象其中的方法来进行反射,拿到字节码方法,在对一个对象进行作用,若方法为静态,则传入的参数为null
//调用str1上的charAt(1); Method methodCharAt = String.class.getMethod("charAt",int.class);//有多少参数,写多少class System.out.println(methodCharAt.invoke(str1, 1)); //反射的方式拿到字节码的方法,<span style="font-family: Arial, Helvetica, sans-serif;">再用该方法作用某个对象</span> // 调用 // System.out.println(methodCharAt.invoke(null, 1)); //静态方法不需要作用对象 //若为null 则该方法为静态方法 //自己写一个程序,用反射的方式调用其他程序中的main String startingClassName = args[0]; Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class); mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
5、数组反射。
通过数组,拿到字节码文件,这里需要提到的是,不同的数组类型 所拿到的字节码文件不同。
int[] a1 = new int[]{1,2,3}; int[] a2 = new int[4]; int[][] a3 = new int[2][3]; String[] a4 = new String[]{"a","b","c"}; System.out.println("a1 a2: " + (a1.getClass() == a2.getClass())); // System.out.println("a1 a3: " + (a1.getClass() == a3.getClass())); // System.out.println("a1 a4: " + (a1.getClass() == a4.getClass())); // 明显类型不匹配,编译报错 System.out.println(a1.getClass().getName());//结果为{I {表示数组,I表示整型 System.out.println(a1.getClass().getSuperclass().getName()); System.out.println(a4.getClass().getSuperclass().getName());//打印父类的名字
以上是我所知道的 五种反射方式。
反射还可以arrays工具类结合使用。
这里需要提到的是JDK1.5以及之前的版本的不同,之前的版本Arrays.asList(obj)接受的为Object类型,但是int属于基本类型,它并不在Object之内,在1.5可变参数的功能加入之后接受的类型变为可变参数,但之前的方法并没有废除,所以,当接受的参数类型为int时,直接交给1.5的方法处理,也就造成 整个数组变成一个整体输出,而不是数组。
System.out.println(Arrays.asList(a1));//int不属于Object类型,故由JDK1.5参数处理 //整形数组就被当成一个整体输出 System.out.println(Arrays.asList(a4));//JDK1.4接受Object参数 printObject(a1); printObject(a4);
private static void printObject(Object obj) throws Exception{ Class cla = obj.getClass(); if(cla.isArray()) { int len = Array.getLength(obj); for(int i=0; i<len; i++) { System.out.println(Array.get(obj, i)); } } else System.out.println(obj); }反射的功能很强大,感觉现在理解的不是很透彻,运用的也不多,希望在日后的学习中能多多接触和运用。
------- android培训、java培训、期待与您交流! ----------
相关文章推荐
- 黑马程序员-JAVA基础加强-反射2
- 黑马程序员--Java基础加强--10.【PropertyDescriptor操作JavaBean VS 反射操作Java类】【个人总结】
- 黑马程序员---java基础加强_成员变量的反射
- 黑马程序员_张孝祥_Java基础加强_反射
- 黑马程序员java学习<基础加强>—反射
- 黑马程序员--JAVA基础加强之反射技术
- 黑马程序员--Java基础加强--15.利用反射操作泛型IV【通过反射Method解析泛型方法思路】【通过Method对四种Type子接口类型进行解剖】【使用递归对任意复合泛型类型进行彻底解剖】【个人
- 黑马程序员_Java基础加强_反射
- 黑马程序员-JAVA基础加强之反射
- 黑马程序员_java基础加强-枚举和反射
- 黑马程序员 20 Java基础加强-02-反射篇
- 黑马程序员--Java基础加强--13.利用反射操作泛型II【TypeVariable】【GenericArrayType】【WildcardType】【Type及其子接口的来历】【个人总结】
- 『黑马程序员』---java--基础加强--反射+内省
- 黑马程序员-Java基础加强-反射
- 黑马程序员--Java基础加强--07.【反射创建对象 操作字段 调用方法的异同】【个人总结】
- 黑马程序员--Java基础加强--12.利用反射操作泛型I【与反射+泛型相关的接口类型综述】【Type】【ParameterizedType】【个人总结】
- 黑马程序员-Java基础加强之反射
- 黑马程序员_java基础加强_静态导入_反射_枚举_注解_内省_泛型_代理
- 【黑马程序员】Java基础加强15:反射Reflect
- 黑马程序员--Java基础加强学习笔记之Class类、反射(Reflect)