一、反射概述
1. java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制.
2.创建对象(在内存中分配一块空间)的方式一共有四种:
(1)使用new关键字实例化.(最常用的)
(2)通过Class.forName("..").newInstance()或java.lang.reflect.Constructor反射手段.//重点讲解
(3)调用对象的clone方法.
(4)运用序列化和反序列化手段.
3.什么是反射
* 剖析java类中的各个组成部分映射成一个个java对象.
* 类java.lang.Class
* java.lang.reflect
* 构造方法Constructor
* 成员变量Field
* 方法Method
4.Class类
* java.lang.Class类用于表示一个类的字节码(.class)文件
* 如何的到某个class文件对应的class对象
(1)已知的类:类名.class
(2)一直对象,但不知道属于哪个类:对象.getClass()
(3)未知类和对象的情况下:Class.forName("完全限定名");
Class.forName方法用于加载类的字节码到内存中,并封装成一个Class对象.
Class类的newInstance()方法用来调用类的默认构造方法.
示例:String obj = (String)Class.forName("java.lang.String").newInstance();
* newInstance()方法只能调用无参构造来实例化对象,当没有默认构造时,这时就需要Class.getConstructor(..)来获取某个构造方法.
示例:
class cls = Class.forName("com.liu.Dog");
Constructor cons = cls.getConstructor(String.class);//假设有一个参数为String类型的构造器
Object obj = cons.newInstance("TomDog");
注意:如果Dog中的构造为私有的,需要打开权限,再实例化
cons.setAccessible(true);
5.Field类
(1)Field对象的获得
* 得到所有的成员变量
Field[] fields = clazz.getgetFields();//取得所有public属性的
Field[] fields = clazz.getDeclaredFields();//取得所有声明的属性,不包含父类中继承下来的
* 得到指定的成员变量
Field name = clazz.getField("name");
Field name = clazz.getDeclaredField("name");
* 设置Field变量是否可以访问
field.setAccessible(boolean);
当访问私有成员变量、final类型的成员变量、静态变量是需要设置为true才可以访问;
访问静态最终变量static final,不允许访问.
* Field变量值的读取,设置
* field.get(obj);
* field.set(obj.value);
6.Method类
* getDeclaredMethods/Fields : 获取用户自定义的属性和方法,不包含从父类中继承的属性和方法.
* getMethods/Fields : 获取所有公共的属性和方法,不包含私有属性和方法.
* 示例:(获取特定方法,并调用)
//假设有Dog这个类,并且有say这个方法.
Class clazz = Class.forName("com.liu.Dog");
Method say = clazz.getMethod("say",String.class);
//调用方法
say.invoke(clazz.newInstance(),"rose");//传入对象,和say方法需要的参数.
* 调用静态方法时不需要传递实例对象,静态方法可以直接调用
//此时假设say为静态方法
say.invoke(null,"param");
常规的静态方法一般是类名.方法名来调用的,即
say.invoke(clazz,"param");//不传对象,而传入类的字节码,更合乎情理.
1. java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制.
2.创建对象(在内存中分配一块空间)的方式一共有四种:
(1)使用new关键字实例化.(最常用的)
(2)通过Class.forName("..").newInstance()或java.lang.reflect.Constructor反射手段.//重点讲解
(3)调用对象的clone方法.
(4)运用序列化和反序列化手段.
3.什么是反射
* 剖析java类中的各个组成部分映射成一个个java对象.
* 类java.lang.Class
* java.lang.reflect
* 构造方法Constructor
* 成员变量Field
* 方法Method
4.Class类
* java.lang.Class类用于表示一个类的字节码(.class)文件
* 如何的到某个class文件对应的class对象
(1)已知的类:类名.class
(2)一直对象,但不知道属于哪个类:对象.getClass()
(3)未知类和对象的情况下:Class.forName("完全限定名");
Class.forName方法用于加载类的字节码到内存中,并封装成一个Class对象.
Class类的newInstance()方法用来调用类的默认构造方法.
示例:String obj = (String)Class.forName("java.lang.String").newInstance();
* newInstance()方法只能调用无参构造来实例化对象,当没有默认构造时,这时就需要Class.getConstructor(..)来获取某个构造方法.
示例:
class cls = Class.forName("com.liu.Dog");
Constructor cons = cls.getConstructor(String.class);//假设有一个参数为String类型的构造器
Object obj = cons.newInstance("TomDog");
注意:如果Dog中的构造为私有的,需要打开权限,再实例化
cons.setAccessible(true);
5.Field类
(1)Field对象的获得
* 得到所有的成员变量
Field[] fields = clazz.getgetFields();//取得所有public属性的
Field[] fields = clazz.getDeclaredFields();//取得所有声明的属性,不包含父类中继承下来的
* 得到指定的成员变量
Field name = clazz.getField("name");
Field name = clazz.getDeclaredField("name");
* 设置Field变量是否可以访问
field.setAccessible(boolean);
当访问私有成员变量、final类型的成员变量、静态变量是需要设置为true才可以访问;
访问静态最终变量static final,不允许访问.
* Field变量值的读取,设置
* field.get(obj);
* field.set(obj.value);
6.Method类
* getDeclaredMethods/Fields : 获取用户自定义的属性和方法,不包含从父类中继承的属性和方法.
* getMethods/Fields : 获取所有公共的属性和方法,不包含私有属性和方法.
* 示例:(获取特定方法,并调用)
//假设有Dog这个类,并且有say这个方法.
Class clazz = Class.forName("com.liu.Dog");
Method say = clazz.getMethod("say",String.class);
//调用方法
say.invoke(clazz.newInstance(),"rose");//传入对象,和say方法需要的参数.
* 调用静态方法时不需要传递实例对象,静态方法可以直接调用
//此时假设say为静态方法
say.invoke(null,"param");
常规的静态方法一般是类名.方法名来调用的,即
say.invoke(clazz,"param");//不传对象,而传入类的字节码,更合乎情理.