实现借助于4个类:
1.class 类对象
2.Constructor 构造器对象
3.Field 类的属性对象
4.Method 方法对象
Java反射的作用:
在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。
对于任意一个对象,可以调用它的任意一个方法。
这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。
1、得到构造器的方法
Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,
Constructor[] getConstructors() -- 获得类的所有公共构造函数
Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关)
Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关)
Field getField(String name) -- 获得命名的公共字段
Field[] getFields() -- 获得类的所有公共字段
Field getDeclaredField(String name) -- 获得类声明的命名的字段
Field[] getDeclaredFields() -- 获得类声明的所有字段
3、获得方法信息的方法
Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法
Method[] getMethods() -- 获得类的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法
Method[] getDeclaredMethods() -- 获得类声明的所有方法
业务方法1类:
package fanshe;
public class Service1 {
public void doService1(){
System.out.println("业务方法1");
}
}
业务方法2类:package fanshe;
public class Service2 {
public void doService2(){
System.out.println("业务方法2");
}
}测试类:
package fanshe;
public class FansheTest {
public static void main(String[] args) {
Service1 S1=new Service1();
S1.doService1();
//Service2 S2=new Service2();
//S2.doService2();
}
}当需要从第一个业务方法切换到第二个业务方法的时候,使用非反射方式,必须修改代码,并且重新编译运行,才可以达到效果.
反射方式:
使用反射方式,首先准备一个配置文件,就叫做spring.txt吧, 放在src目录下。 里面存放的是类的名称,和要调用的方法名。
在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。
当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件spring.txt,再运行即可。
配置文件spring.txt
业务方法1类:
package fanshe;
public class Service1 {
public void doService1(){
System.out.println("业务方法1");
}
}业务方法2类:
package fanshe;
public class Service2 {
public void doService2(){
System.out.println("业务方法2");
}
}测试类:
package fanshe;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class FansheTest {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//1.获取配置文件
File SpringConfigFile=new File("/Users/zhang/Desktop/spring.txt");
Properties SpringConfig=new Properties();
SpringConfig.load(new FileInputStream(SpringConfigFile));
//获取配置文件类名
String ClassName=(String) SpringConfig.get("class");
System.out.println("类名===="+ClassName);
//获取方法名
String MethodName=(String) SpringConfig.get("method");
System.out.println("方法名===="+MethodName);
//根据类名创建对象
Class clazzz=Class.forName(ClassName);
//根据方法名称,获取方法
Method m=clazzz.getMethod(MethodName);
//获取构造器
Constructor c=clazzz.getConstructor();
//根据构造器实例化对象
Object service=c.newInstance();
m.invoke(service);
/* 可以看到Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor来处理。
每个实际的Java方法只有一个对应的Method对象作为root。
这个root是不会暴露给用户的,而是每次在通过反射获取Method对象时新创建Method对象把root包装起来再给用户。
在第一次调用一个实际Java方法对应得Method对象的invoke()方法之前,实现调用逻辑的MethodAccessor对象还没创建;
等第一次调用时才新创建MethodAccessor并更新给root,然后调用MethodAccessor.invoke()真正完成反射调用。
*/
}
}打印结果:
类名====fanshe.Service1
方法名====doService1
业务方法1
链接:https://www.zhihu.com/question/24304289/answer/150310001
Java反射机制详解
本文深入介绍了Java反射机制的基础概念及其实现方式,包括如何利用反射获取类的构造器、字段和方法信息,以及如何动态调用对象的方法。通过具体示例展示了如何在不修改源代码的情况下,仅通过更改配置文件实现不同业务方法之间的切换。
295

被折叠的 条评论
为什么被折叠?



