Java 反射机制 示例

实现借助于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() -- 获得类的所有构造函数(与接入级别无关)

2、获得字段信息的方法
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







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值