反射

1、概念

优点:
	用于开发时项目分组的情况下,提前模拟类,方法项目进度使用
	提高开发灵活度,提高程序的扩展性
缺点:
	破坏封装,性能低下

2、常用方法

1. 获取字节码文件
		1. Class clazz  = Class.forName(全限定路径名) (最多使用)
			static 类<?> forName(String name, boolean initialize, ClassLoader loader) 
				使用给定的类加载器返回与给定字符串名称的类或接口相关联的 类对象。 
		2. 全限定类名.class
		3. 对象名.getClass()
			
2. 根据字节码文件获取构造方法、普通方法、字段等
		构造方法
		Constructor[] constructors = clazz.getConstructors() 获取public修饰的构造方法数组
		Constructor[] constructors = clazz.getDeclaredConstructors() 获取所有造方法数组
		Constructor constructor = clazz.getConstructor(Class 参数字节码)根据参数类型获取指定的的构造方法
		
		//通过构造方法对象去用构造方法创建对象 => 相当于new 一个对象
		Object instance  = constructor.newInstance(Object 实参);

		普通方法
		Method[] methods = clazz.getMethods() 获取public修饰的普通方法数组
		Method[] methods = clazz.getDeclaredMethods() 获取所有普通方法数组
		Method method = clazz.getMethod(String methodName,Class... 参数字节码)根据方法名和参数类型获取指定的的方法
		如果方法没有形参,则Class可变参数不用写
		
		//通过普通方法对象调用执行方法
		method.invoke(Object 对象,Object... args);
		如果是对象的方法,对象就是上面创建的instance,如果是static方法,则写null
		args:就是具体实参
		
		字段
		Field[] fields = clazz.getFields() 获取public修饰的字段数组
		Field[] fields = clazz.getDeclaredFields() 获取所有权限的字段数组
		Field field = clazz.getDeclearField(String fieldName) 根据字段名获取指定字段
		Field field = clazz.Field(String fieldName)根据字段名获取指定public修饰字段
		
		//通过当前的字段对象,给某一个字段赋值取值
		field.get(Object obj);
		field.set(Object obj, Object value);
				
				

 		String getName()  获取全限定类名(全限定,包含包名)
 		String getSimpleName()   获取类名简称		
 
 			Package getPackage()   获取包名
 			
 *		注意事项:
 *			T newInstance()  根据当前字节码创建对应的对象,只能创建无参构造的对象

3、具体代码实现

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 *  通过反射操做对象
 */
public class ReflectTest2 {

	public static void main(String[] args) throws Exception {
	
		//拿到字节码文件(根据完全限定名)
		Class<?> clazz = Class.forName("cn.itsource.reflect.User");
		
		/*
		 * 构造方法
		 */
		//获取到所以的构造方法,包括私有化的(通过传入的参数类型字节码,获取到对应的构造方法)
		Constructor<?> constructor = clazz.getDeclaredConstructor(String.class,int.class,boolean.class);
		//如果参数是true,破坏封装性。得到私有化的构造方法
		//constructor.setAccessible(true);
		//传入具体的参数(给字段设置值),得到实例对象
		Object instance = constructor.newInstance("张三",20,true);
		
		
		/*
		 * 字段
		 */
		//通过字节码对象,获取到所有的字段  (里面传入类里面参数的具体名称)
		Field field = clazz.getDeclaredField("name");
		//破坏封装,得到private修饰的字段。如果是public修饰的,就不需要写
		field.setAccessible(true);
		
		//给字段设置值。参数1:需要操作的是哪个实例对象里面的字段(如果该字段是static修饰的,那么参数一就可以写:null),参数2:具体的值
		field.set(instance, "李四");
		//获取的字段的值(根据传入的实例对象获取对应的字段值)
		Object object = field.get(instance);
		System.out.println("字段:"+object);
		
		
		/*
		 * 普通方法
		 */
		//通过字节码对象,获取里面所有的方法(参数1:方法名称    参2:该方法内,参数类型的字节码(可变参数,可以写多个))
		Method method = clazz.getDeclaredMethod("add",String.class,int.class);
		//通过方法的对象,调用里面的方法       参数1:需要操作的类(实例对象)如果该方法是static修饰的,那么参数1是可以写null    参数2:具体的值,可变参数可以写多个(没有就不写)
		Object invoke = method.invoke(instance, "具体的值",1);
		System.out.println("方法:"+invoke);
		
		
		//获取完全限定名
		String name = clazz.getName();
		System.out.println("完全限定名:"+name);
		//获取到简写的名字
		String simpleName = clazz.getSimpleName();
		System.out.println("简写:"+simpleName);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值