一、反射的定义
Java的反射是指在运行状态中,对于任何一个类,都能获取这个类的所有属性和方法;对于任何一个对象,都能调用这个对象的属性和方法,这种动态获取信息以及动态调用对象的方法的功能称为Java的反射机制。
要想剖析一个类,必须获取到该类的字节码文件对象。剖析所使用的就是Class类中的方法,所以要先获取每一个字节码文件所对应的Class类型的对象。
二、反射的原理与用法
1.原理
反射就是把Java类中的各种成分映射成一个个的Java对象
例如,一个类中包括成员变量、成员方法、构造器、包等,利用反射技术对这个类进行剖析,把各个组成部分映射成一个个的对象。
下图是反射的原理:
Class对象的由来是将.class文件读入内存,并自动创建一个Class对象
2.获取Class对象的三种方式
1.通过对象的.getClass()方法获取
2.任何类型都有一个.class属性
3.通过Class类的静态方法:Class.forName(String className)
常用方法3,第1种需要实例化对象,第2种需要导入类的包。
/**
* 获取Class对象的3种方法
* 1: Object---getClass();
* 2.任何数据类型(包括基本数据类型)都有一个”静态“的class属性
* 3.通过Class类的静态方法:Class.forName(String className)
*/
class Student{}
public class Fanshe {
public static void main(String[] args) {
//1.通过getClass方法获取对象
Student stu = new Student();//通过new方法产生两个对象,一个是Student对象,一个是Class对象
Class stuClass = stu.getClass();//获取Class对象
System.out.println(stuClass.getName());
//2.通过.class方法获取对象
Class stuClass2 = Student.class;
System.out.println(stuClass2.getName());
//3.通过Class.forName方法
try {
Class stuClass3 = Class.forName("Student");
System.out.println(stuClass3.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
3.通过反射获取构造方法
1.public Constructor[] getConstructors():所有的共有的构造方法
2.public Constructor[] getDeclaredConstructors():获取所有的构造方法
3.public Constructor getConstructor(Class parameterTypes):获取单个的公有构造方法
4.public Constructor getDeclaredConstructors(Class...parameterTypes):获取单个的构造方法(无论公有私有)
5.调用构造方法.newInstance
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Constructors {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取Class对象
Class clazz = Class.forName("Student");
//2.获取所有的公有构造方法
Constructor[] cons = clazz.getConstructors();
for(Constructor c:cons){
System.out.println(c);
}
//3.获取所有的构造方法
System.out.println("获取所有的构造方法");
Constructor[] cons2 = clazz.getDeclaredConstructors();
for(Constructor c:cons2){
System.out.println(c);
}
//4.获取单个的公有的构造方法
System.out.println("获取单个的公有的构造方法");
Constructor con = clazz.getConstructor(char.class);
System.out.println(con);
//5.获取无论共有还是私有的构造方法
System.out.println("5.获取无论共有还是私有的构造方法");
Constructor con2 = clazz.getDeclaredConstructor(int.class);
System.out.println(con2);
//6.调用构造方法
System.out.println("调用构造方法");
con.newInstance('y');
}
}
4.通过反射获取构成员变量
1、Field[] getFields()获取所有的公有成员变量
2、Field[] getDeclaredFields()获取所有的成员变量
3、public Field getField(String fieldName)获取指定的公有成员变量
4、public Field getDeclaredField(String fieldNname)获取指定的成员变量
5、设置成员变量的值:
Filed------>public void set(Object obj, Object value)
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* 反射方法获取成员变量
*/
public class Fields {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class stuClass = Class.forName("Student2");
//2.获取所有的公有成员变量
System.out.println("获取所有的公有成员变量");
Field[] fields = stuClass.getFields();
for(Field f:fields){
System.out.println(f);
}
//2.获取所有的成员变量(不管是公有的还是私有)
System.out.println("2.获取所有的成员变量(不管是公有的还是私有)");
Field[] fields1 = stuClass.getDeclaredFields();
for(Field f:fields1){
System.out.println(f);
}
//3.获取单个公有成员变量
System.out.println("获取单个公有成员变量");
Field field = stuClass.getField("name");
System.out.println(field);
Student2 stu2 = new Student2();
field.set(stu2,"周杰伦");
System.out.println(stu2.name);
}
}
5.通过反射获取构成员方法
1、pubic Method[] getMethods():获取所有的公有成员方法(包括继承的父类方法也包括Object类)
2、public Method[] getDeclaredMethods():获取所有的成员方法()不包括继承的
3、public Method getMethod(String name,Class<?>... parameterTypes)获取指定的公有的成员方法
4、public Method getDeclaredMethod(String name,Class<?>... parameterTypes)获取指定的成员方法
调用方法:Method---public Object invoke(Object obj, Object... args)
import java.lang.reflect.Method;
public class MethodClass {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class stuClass = Class.forName("Student3");
//1.获取公有成员方法(包括父类方法)
System.out.println("获取公有成员方法(包括父类方法和Object类)");
Method[] methods = stuClass.getMethods();
for(Method m:methods){
System.out.println(m);
}
//2.获取所有的成员方法(不包括父类的方法)
System.out.println("获取所有的成员方法(不包括父类的方法)");
Method[] methods2 = stuClass.getDeclaredMethods();
for(Method m:methods2){
System.out.println(m);
}
//3.获取指定的公有成员方法
System.out.println("获取指定的公有成员方法");
Method method = stuClass.getMethod("show1",String.class);
System.out.println(method);
//调用方法
Student3 stu3 = new Student3();
method.invoke(stu3,"周杰伦");
}
}