哎,总想写出一篇能够浅显易懂的博客出来,让大家一看就明白,可惜自己写的博客也只有自己看得懂
闲来无事,看了一下现在做的项目的框架,发现里面用到了反射,突然就想研究一下这种高大上的东西,所以就看了几篇博客,自己敲了几行代码,顿时觉得自己已经“理解”了,哈哈,
自己毕竟是练武奇才。扯远了,还是回到JAVA反射机制上来。
1. Java反射机制的概念
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制
2.JAVA反射的大体步骤
A.知道类的名称获取这个类
B.获得类后获取类的方法和属性
C.根据这个类创建一个实例,再用实例来调用方法来完成相应的逻辑。
3.举个例子来说明一下 创建一个学生类和一个老师类
/**
*
* @author user
*
*/
public class Teacher {
public void getTeacherInfo(String name){
System.out.println("这个老师的姓名是:"+name);
}
public void getTeacherInfo(String name,String school,String sex,Integer age){
System.out.println("这个老师的姓名是:"+name+",性别是:"+sex+",年龄是:"+age+",所在学校是:"+school);
}
}
package reflectTest;
public class Student {
public void getStudentInfo(){
System.out.println("我就是一名学生");
}
public String getStudentInfo(String name,String school){
System.out.println("我就是一名叫"+name+"的学生,来自"+school);
return name;
}
}
package reflectTest;
import java.lang.reflect.Method;
/**
* 测试类
* @author user
*
*/
public class ReflectTest {
@SuppressWarnings({ "rawtypes", "static-access", "unused", "unchecked" })
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
try {
//forName("className")里面的className必须为全名,也就是得包含包名
//根据类名获取这个类
Class<?> classTeacher = Class.forName("reflectTest.Teacher");
//对这个类进行实例化
Object objectTeacher = classTeacher.newInstance();
Class[] paramTypesOne = new Class[4];
paramTypesOne[0] = String.class;
paramTypesOne[1] = String.class;
paramTypesOne[2] = String.class;
paramTypesOne[3] = Integer.class;
//根据方法名和参数数组获取这个类的某个方法
Method teacherMethodOne = classTeacher.getMethod("getTeacherInfo", paramTypesOne);
//方法参数以数据的形式来传递
Object[] argsObjectOne ={"王文海","三合中学","男",32};
//执行objectTeacher对象的这个方法
teacherMethodOne.invoke(objectTeacher, argsObjectOne);
Class[] paramTypesTwo = new Class[1];
paramTypesTwo[0] = String.class;
//即使方法名一样,但所传的参数类型不一样,获得的方法也不一样
Method teacherMethodTwo = classTeacher.getMethod("getTeacherInfo", paramTypesTwo);
Object[] argsObjectTwo ={"韩立"};
teacherMethodTwo.invoke(objectTeacher, argsObjectTwo);
Class studentClass=classTeacher.forName("reflectTest.Student");
Object studentObject = studentClass.newInstance();
Class[] parameterTypes = new Class[2];
parameterTypes[0] = String.class;
parameterTypes[1] = String.class;
Method studentMethod = studentClass.getMethod("getStudentInfo", parameterTypes);
Object[] argsObject ={"张三","清华大学"};
//还可以获得返回值
Object studentName = studentMethod.invoke(studentObject, argsObject);
System.out.println("这个学生的姓名是:"+studentName);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果:
这个老师的姓名是:王文海,性别是:男,年龄是:32,所在学校是:三合中学
这个老师的姓名是:韩立
我就是一名叫张三的学生,来自清华大学
这个学生的姓名是:张三
4.反射中常用到的方法:
获得构造函数的方法
Constructor getConstructor(Class[] params)//根据指定参数获得public构造器
Constructor[] getConstructors()//获得public的所有构造器
Constructor getDeclaredConstructor(Class[] params)//根据指定参数获得public和非public的构造器
Constructor[] getDeclaredConstructors()//获得public的所有构造器
获得类方法的方法
Method getMethod(String name, Class[] params),根据方法名,参数类型获得方法
Method[] getMethods()//获得所有的public方法
Method getDeclaredMethod(String name, Class[] params)//根据方法名和参数类型,获得public和非public的方法
Method[] getDeclaredMethods()//获得所以的public和非public方法
获得类中属性的方法
Field getField(String name)//根据变量名得到相应的public变量
Field[] getFields()//获得类中所以public的方法
Field getDeclaredField(String name)//根据方法名获得public和非public变量
Field[] getDeclaredFields()//获得类中所有的public和非public方法