Java反射小总结
2015-02-08 01:20
232 查看
Java反射小总结
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
在反射之下,我们平常对Java的好认知都要改变,比如private进行访问控制,泛型可以限制容器内元素的类型等概念都要有所调整。可以说反射是Java语言中的核心特点之一。现在我们所使用的成熟的框架如Spring,Hibernate等等,都是因为大量使用反射才能很好的实现。
利用java的反射,我们可以在不清楚一个类内部情况下动态地分析这个类,并对这个类或其实例进行操作。下面对反射进行分析。
Java反射反射所用到的类,接口和异常都在java.lang.reflect包中,下面是JDK7u65API中各类的说明。
介绍几个常的接口和类:
1, Constructor: 提供了一个构造函数的信息以及访问类的构造函数的接口。
2, Field: 提供一个类的域的信息以及访问类的域的接口。
3, Method: 提供一个类的方法的信息以及访问类的方法的接口。
4, Array: 该类提供动态地生成和访问JAVA数组的方法。
5, AccessibleObject: 该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。
6, Modifie: 提供了 static 方法和常量,对类和成员访问修饰符进行解码。
7, Proxy: 提供动态地生成代理类和类实例的静态方法。(不太明白)。
再讲反射中最重要的一个类Class.
它位于Java.lang包中,其API信息太多,不示切图了,用到哪个说哪个吧!
要想运用反射首先要得到Class对象。老生常谈的问题,得到Class类的三个方法。
1, 调用任何对象的getClass()方法
如Class<?> classType1 = ”HelloWorld!”.getClass();
2, 在类后加.class
如Class<?> classType2 = String.class;
3, 运用Class类的一个静态方法,forName(StringclassName)
如Class<?> classType3 = Class.forName(“java.lang.String”);
在些要说明的一点是,这三种类型,classType1~3是==的,而且是equals的,我们平常使用时,如果要对比两个类型是否是一样的,直接用==,因为相同类型在Java中只有一ww发字节码,用==完全没有问题,且提倡使用==。
4, 还有一种特别的类型,就是基本类型,它们也是有对应的Class的,通过类似于int.class或Integer.TYPE来得到。再有其实void也是有对应的Class的。就是在JAVA中所有的结成部分都有对应的Class。
得到Class后,下面就正式开始运用Class进行一些操作。
获取Fields有两组四个方法:
1, public FieldgetField(String name),返回一个 Field 对象,它反映此 Class对象所表示的类或接口的指定公共成员字段。
2, public Field[] getFields(),返回一个包含某些 Field 对象的数组,这些对象反映此Class 对象所表示的类或接口。
3, public FieldgetDeclaredField(Stringname),返回一个 Field 对象,该对象反映此Class 对象所表示的类或接口的指定已声明字段。
4, public Field[] getDeclaredFields(),返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段
其中的带declaredField的方法可以得到被声明为private的成员,其中Field对象是包装了一个成员的对象。要对私有的成员或方法进行访问的时候要先进行暴力设定为可访问setAccessible(true),之后就可以与public的成员一样进行访问了。
见下面代码:
下面的反射得到Method,得到构造方法都与这个得到成员是类似的,就不去浪费时间叙述,需要的可以去查看API
通过反射建立对象
1, 调用没有参数的构造方法,分两种方法。
a) 在得到所需要的类的Class对象后,通过newInstance()方法来得到新的对象。
b) 得到Class对象后,调用其getConstructor()方法,得到空参数的构造方法对应的对象。再调用构造方法的对象的newInstance()方法来得到所需的对象。
2, 调用有参数的构造方法的newInstance()方法,如:
Constructor<?> constructor = classType.getDeclaredConstructor(int.class,String.class);
Object abc = constructor. newInstance(1, ”123”);
下面代码有说明:
对得到的成员设置值
Field中有setXXX()和getXXX()方法,其中的XXX是指类型,比较简单,看代码;
调用得到的方法
通过Method对象的invoke方法来调用对应的方法:
说明性代码:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
在反射之下,我们平常对Java的好认知都要改变,比如private进行访问控制,泛型可以限制容器内元素的类型等概念都要有所调整。可以说反射是Java语言中的核心特点之一。现在我们所使用的成熟的框架如Spring,Hibernate等等,都是因为大量使用反射才能很好的实现。
利用java的反射,我们可以在不清楚一个类内部情况下动态地分析这个类,并对这个类或其实例进行操作。下面对反射进行分析。
Java反射反射所用到的类,接口和异常都在java.lang.reflect包中,下面是JDK7u65API中各类的说明。
介绍几个常的接口和类:
1, Constructor: 提供了一个构造函数的信息以及访问类的构造函数的接口。
2, Field: 提供一个类的域的信息以及访问类的域的接口。
3, Method: 提供一个类的方法的信息以及访问类的方法的接口。
4, Array: 该类提供动态地生成和访问JAVA数组的方法。
5, AccessibleObject: 该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。
6, Modifie: 提供了 static 方法和常量,对类和成员访问修饰符进行解码。
7, Proxy: 提供动态地生成代理类和类实例的静态方法。(不太明白)。
再讲反射中最重要的一个类Class.
它位于Java.lang包中,其API信息太多,不示切图了,用到哪个说哪个吧!
要想运用反射首先要得到Class对象。老生常谈的问题,得到Class类的三个方法。
1, 调用任何对象的getClass()方法
如Class<?> classType1 = ”HelloWorld!”.getClass();
2, 在类后加.class
如Class<?> classType2 = String.class;
3, 运用Class类的一个静态方法,forName(StringclassName)
如Class<?> classType3 = Class.forName(“java.lang.String”);
在些要说明的一点是,这三种类型,classType1~3是==的,而且是equals的,我们平常使用时,如果要对比两个类型是否是一样的,直接用==,因为相同类型在Java中只有一ww发字节码,用==完全没有问题,且提倡使用==。
4, 还有一种特别的类型,就是基本类型,它们也是有对应的Class的,通过类似于int.class或Integer.TYPE来得到。再有其实void也是有对应的Class的。就是在JAVA中所有的结成部分都有对应的Class。
得到Class后,下面就正式开始运用Class进行一些操作。
获取Fields有两组四个方法:
1, public FieldgetField(String name),返回一个 Field 对象,它反映此 Class对象所表示的类或接口的指定公共成员字段。
2, public Field[] getFields(),返回一个包含某些 Field 对象的数组,这些对象反映此Class 对象所表示的类或接口。
3, public FieldgetDeclaredField(Stringname),返回一个 Field 对象,该对象反映此Class 对象所表示的类或接口的指定已声明字段。
4, public Field[] getDeclaredFields(),返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段
其中的带declaredField的方法可以得到被声明为private的成员,其中Field对象是包装了一个成员的对象。要对私有的成员或方法进行访问的时候要先进行暴力设定为可访问setAccessible(true),之后就可以与public的成员一样进行访问了。
见下面代码:
下面的反射得到Method,得到构造方法都与这个得到成员是类似的,就不去浪费时间叙述,需要的可以去查看API
通过反射建立对象
1, 调用没有参数的构造方法,分两种方法。
a) 在得到所需要的类的Class对象后,通过newInstance()方法来得到新的对象。
b) 得到Class对象后,调用其getConstructor()方法,得到空参数的构造方法对应的对象。再调用构造方法的对象的newInstance()方法来得到所需的对象。
2, 调用有参数的构造方法的newInstance()方法,如:
Constructor<?> constructor = classType.getDeclaredConstructor(int.class,String.class);
Object abc = constructor. newInstance(1, ”123”);
下面代码有说明:
对得到的成员设置值
Field中有setXXX()和getXXX()方法,其中的XXX是指类型,比较简单,看代码;
调用得到的方法
通过Method对象的invoke方法来调用对应的方法:
说明性代码:
<span style="font-size:14px;">package cn.com.taiji.test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class TestReflect { public static void main(String[] args) throws Exception { //得到了Class Class<Arm> clazz = Arm.class; //得到Field Field f0 = clazz.getField("i"); Field f1 = clazz.getField("str1"); // Field f2 = clazz.getField("str2");//运行时抛异常,这个方法不能访问到私有成员 System.out.println(f1); //public java.lang.String cn.com.taiji.test.Arm.str1 Field f3 = clazz.getDeclaredField("str1"); System.out.println(f3);//public java.lang.String cn.com.taiji.test.Arm.str1 Field f4 = clazz.getDeclaredField("str2"); System.out.println(f4);//public java.lang.String cn.com.taiji.test.Arm.str2 //getFields方法可以得到所有能正常访问到的方法,将其组成一个数组,getDeclaredFields类似 //得到构造方法, Constructor<Arm> constructor1 = clazz.getConstructor(); Constructor<Arm> constructor2 = clazz.getConstructor(String.class, String.class); //得到实例 Arm a1 = clazz.newInstance(); Arm a2 = constructor1.newInstance(); Arm a3 = constructor2.newInstance("def", "456"); System.out.println(a1);//str1:abc====str2:123 System.out.println(a2);//str1:abc====str2:123 System.out.println(a3);//str1:def====str2:456 //访问Field,引用类型 System.out.println(f1.get(a1)); f1.set(a1, "cba"); System.out.println(a1.getStr1()); // System.out.println(f4.get(a1));//报异常,现在不能访问 f4.setAccessible(true); System.out.println(f4.get(a1));//可以访问 //访问基本类型,两个都可以 System.out.println(f0.get(a1));//返回的是Object类型 System.out.println(f0.getInt(a1));//返回的是int类型 //得到Method,执行方法,不带参数 Method method1 = clazz.getMethod("m1"); System.out.println(method1);//public void cn.com.taiji.test.Arm.m1() method1.invoke(a1);//m1 run //带参数的 Method method2 = clazz.getDeclaredMethod("m2", int.class); System.out.println(method2);//private void cn.com.taiji.test.Arm.m2(int) //设定访问权限 method2.setAccessible(true); System.out.println(method2);//private void cn.com.taiji.test.Arm.m2(int) method2.invoke(a1, 3);//m2 run:3 } } class Arm { public String str1; public int i; private String str2; public Arm() { str1 = "abc"; str2 = "123"; i = 11; } @Override public String toString() { return "str1:" + str1 + "====" + "str2:" + str2; } public Arm(String str1, String str2) { super(); this.str1 = str1; this.str2 = str2; } public void m1() { System.out.println("m1 run"); } private void m2(int ss) { System.out.println("m2 run:" + ss); } public String getStr1() { return str1; } public void setStr1(String str1) { this.str1 = str1; } public String getStr2() { return str2; } public void setStr2(String str2) { this.str2 = str2; } }</span>
相关文章推荐
- java 反射 总结
- java反射总结
- Java 反射获取类详细信息的常用方法总结
- 黑马程序员_java反射总结
- 基于java中反射的总结分析
- java 反射的一些使用总结
- 黑马程序员:Java基础总结----反射
- java反射reflect学习总结
- 黑马程序员__JAVA高新技术--反射、注解总结
- Java增强_反射的总结
- java 反射 总结
- Java基础加强反射总结
- 黑马程序员___java反射的总结
- 黑马程序员 Java高新技术 反射总结
- java中的反射总结
- java 反射 总结
- java 反射知识总结
- Core Java第十六章知识点总结——反射
- Java 反射机制简单总结
- Java反射与内省机制总结