1 反射机制
1、介绍
JAVA反射机制实在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为JAVA反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。
通俗来讲,反射就是通过class文件对象,去使用该文件中的成员变量、构造方法、成员方法。
Class类:
成员变量:Field
构造函数:Constructor
成员方法:Method
2、获取calss文件对象的方式
- Object类的getClass()方法
- 数据类型的静态属性class
- Class类中的静态方法:public static Class forName(String className)
在开发中一般使用第三种,因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。
1.1、通过反射获取构造方法并使用
1、获取构造方法:
- public Constructor[] getConstructors();所有公共构造方法
- public Constructor[] getDeclaredConstructors();所有构造方法
- public Constructor<T> getConstructor(Class... parameterTypes);单个公共构造方法
参数表示:要获取的构造方法的构造参数的个数及数据类型的class字节码文件对象。、 - public Constructor<T> getDeclaredConstructor(Class... parameterTypes);单个任意构造方法
2、获取无参构造方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//获取字节码对象
Class c = Class.forName("cn.ref.Person");
//获取单个构造方法
Constructor con = c.getConstructor();//返回的是构造方法对象
//通过获取的构造方法创建一个新实例
Object obj = con.newInstance();
System.out.println(obj);
Person p = (Person)obj;
p.function();
}
}
3、获取带参构造方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//获取字节码对象
Class c = Class.forName("cn.ref.Person");
//获取带参构造方法
Constructor con = c.getConstructor(String.class,int.class,String.class);//返回的是构造方法对象
//通过获取的构造方法创建一个新实例
Object obj = con.newInstance("张三",20,"男");
System.out.println(obj);
Person p = (Person)obj;
System.out.println(p.getName());
}
}
4、获取私有构造方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 获取字节码对象
Class c = Class.forName("cn.ref.Person");
// 获取私有构造方法
Constructor con = c.getDeclaredConstructor(String.class);// 返回的是构造方法对象
//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
con.setAccessible(true);//设置为true才能访问私有,否则报java.lang.IllegalAccessException
// 通过获取的构造方法创建一个新实例
Object obj = con.newInstance("张三");
System.out.println(obj);
Person p = (Person) obj;
System.out.println(p.getName());
}
}
1.2、通过反射获取成员变量并使用
1、获取成员变量
- public Field getField(String name);获取单个公共成员变量
- public Field getDeclaredField(String name);获取单个任意成员变量
- public Field[] getFields();获取所有公共成员变量
- public Field[] getDeclaredFields();获取所有成员变量
2、获取公共成员变量并使用
package cn.ref;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 获取字节码对象
Class c = Class.forName("cn.ref.Person");
//通过构造方法创建一个实例
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 获取成员变量
Field f = c.getField("sex");
//赋值
f.set(obj, "女");
System.out.println(obj);
Person p = (Person) obj;
System.out.println(p.getSex());
}
}
3、获取私有成员变量并使用
package cn.ref;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 获取字节码对象
Class c = Class.forName("cn.ref.Person");
//通过构造方法创建一个实例
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 获取成员变量
Field f = c.getDeclaredField("name");
f.setAccessible(true);
//赋值
f.set(obj, "张三");
System.out.println(obj);
Person p = (Person) obj;
System.out.println(p.getName());
}
}
1.3、通过反射获取成员方法并使用
1、获取成员方法
- public Method getMethod(String name, Class... parameterTypes);获取单个公共成员方法
- public Method getDeclaredMethod(String name, Class... parameterTypes);获取单个任意成员方法
- public Method[] getMethods();获取所有公共成员方法
- public Method[] getDeclaredMethods();获取所有成员方法
2、获取无参无返回值成员方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 获取字节码对象
Class c = Class.forName("cn.ref.Person");
//通过构造方法创建一个实例
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 获取无参成员方法
Method m = c.getMethod("function");
//调用方法
m.invoke(obj);
}
}
3、获取带参带返回值成员方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 获取字节码对象
Class c = Class.forName("cn.ref.Person");
// 通过构造方法创建一个实例
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 获取带参成员方法
Method m = c.getMethod("function",String.class,int.class);
// 调用方法
Object o = m.invoke(obj,"hello",20);
System.out.println(o);
}
}
4、获取私有成员方法并使用
package cn.ref;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 获取字节码对象
Class c = Class.forName("cn.ref.Person");
// 通过构造方法创建一个实例
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 获取私有成员方法
Method m = c.getDeclaredMethod("show");
m.setAccessible(true);
// 调用方法
m.invoke(obj);
}
}
|
|