反射
时间:2016-11-5 21:59
1、反射的原理
反射应用在一些通用性比较高的代码中。
绝大多数Java框架都是通过反射来实现的。
在框架开发中,都是基于配置文件进行开发。
在配置文件中配置了类之后,可以通过反射来得到类中的所有内容,可以执行类中的某个方法,不需要创建对象。
类中的内容:
无参构造
有参构造
成员属性
成员方法
分析反射原理:
首先需要把Java文件保存到本地硬盘。
编译java文件,生成.class字节码文件。
使用JVM,把class文件通过类加载到内存中。
class文件在内存中使用Class类表示。
当使用反射的时候,首先需要获取到Class类,得到这个类的对象之后,就可以得到这个类的所有内容。
包括构造方法、属性、普通方法。
构造方法:Constructor
属性:Filed
普通方法:Method
2、使用反射获取Class类对象
4、使用反射操作属性
/***************************************************************************/
5、使用泛型操作普通方法
使用Method类表示普通方法。(setName)
当操作的方法是静态方法的时候,就不需要创建实例了,可以直接通过类名来调用。
当使用反射操作静态方法的时候,也不需要实例对象:
m.invoke(null, "哈哈");
参数为null,表示这是一个静态方法。
6、方法总结
Class forName(String ClassURL)
获取类对象。
Constructor getConstructor(Object...)
获取构造方法。
Object newInstance(Object...)
创建实例对象。
Field getDeclaredField(String FieldName)
根据名称获取属性。
void setAccessiable(boolean flag)
设置私有属性是否可以访问。
void set(Object obj, Object value...)
执行指定实例对象的方法。
obj:实例对象
value:方法参数
void get(Object obj)
执行指定实例对象的方法。
Method getDeclaredMethod(String methodName, Class argsClass...)
根据方法名和参数列表获取方法。
void invoke(Object obj, Object value...)
执行指定实例的方法,并传递参数列表。
分析反射原理:
首先需要把Java文件保存到本地硬盘。
编译java文件,生成.class字节码文件。
使用JVM,把class文件通过类加载到内存中。
class文件在内存中使用Class类表示。
当使用反射的时候,首先需要获取到Class类,得到这个类的对象之后,就可以得到这个类的所有内容。
包括构造方法、属性、普通方法。
构造方法:Constructor
属性:Filed
普通方法:Method
2、使用反射获取Class类对象
//获取Class类
Class p1 = Person.class;
Class p2 = new Person().getClass();
Class p3 = Class.forName("fanshe.Person");
要对一个类进行实例化,如果不使用new,怎么获取?
Person p = (Person) Class.forName("fanshe.Person").newInstance();
3、操作有参数的构造方法:
构造方法必须是public。
要对一个类进行实例化,如果不使用new,怎么获取?
Person p = (Person) Class.forName("fanshe.Person").newInstance();
3、操作有参数的构造方法:
构造方法必须是public。
//得到Class类对象
Class c = Class.forName("fanshe.Person");
//得到所有的构造方法(不常用)
//c.getConstructors();
//根据参数列表获取构造方法,传递的参数是参数类型的类
Constructor cs = c.getConstructor(String.class, String.class);
//此时已经获取到有参构造方法
//使用有参构造方法创建对象
Person p = (Person)cs.newInstance("张三","1");
//获取Person属性
System.out.println(p.getName());
4、使用反射操作属性
//得到Class类
Class c = Class.forName("fanshe.Person");
//得到Person类实例
Person p = (Person) c.newInstance(); //需要执行强制类型转换
//获取所有属性(不常用)
//Field[] f = c.getDeclaredFields();
//得到name属性
Field name = c.getDeclaredField("name");
//将私有属性设置为可访问(私有属性默认为false,不允许操作)
name.setAccessible(true);
//设置name值
name.set(p, "王五");//相当于p.name = "王五",第一个参数是实例对象,第二个参数是赋值的值
//获取name值
System.out.println(name.get(p));//相当于p.name,传递的参数是实例对象
/***************************************************************************/
getDeclaredField是可以获取一个类的所有字段.
getField只能获取类的public 字段
/***************************************************************************/
/***************************************************************************/
5、使用泛型操作普通方法
使用Method类表示普通方法。(setName)
//得到Class类
Class c = Class.forName("fanshe.Person");
//获取Person实例
Person p = (Person)c.newInstance();
//得到所有的普通方法(不常用)
//c.getDeclaredMethods();
//得到setName(),第一个参数是方法名,第二个参数是参数类型的类
Method m = c.getDeclaredMethod("setName", String.class);
//如果操作的是私有方法,需要将访问权限设置为true
m.setAccessible(true);
//如果操作的是私有方法,需要将访问权限设置为true
m.setAccessible(true);
//执行Method方法
m.invoke(p, "赵六"); //第一个参数是实例对象,第二个参数是方法参数
//获取getName()
Method g = c.getDeclaredMethod("getName");
//执行getName方法
System.out.println(g.invoke(p));
当操作的方法是静态方法的时候,就不需要创建实例了,可以直接通过类名来调用。
当使用反射操作静态方法的时候,也不需要实例对象:
m.invoke(null, "哈哈");
参数为null,表示这是一个静态方法。
6、方法总结
Class forName(String ClassURL)
获取类对象。
Constructor getConstructor(Object...)
获取构造方法。
Object newInstance(Object...)
创建实例对象。
Field getDeclaredField(String FieldName)
根据名称获取属性。
void setAccessiable(boolean flag)
设置私有属性是否可以访问。
void set(Object obj, Object value...)
执行指定实例对象的方法。
obj:实例对象
value:方法参数
void get(Object obj)
执行指定实例对象的方法。
Method getDeclaredMethod(String methodName, Class argsClass...)
根据方法名和参数列表获取方法。
void invoke(Object obj, Object value...)
执行指定实例的方法,并传递参数列表。