Java反射

一、Java反射的使用场景

暂时只用过通过配置文件的className来创建对象。

“很多人都觉得,既然都知道类名,为什么不直接new出来,然后调用方法,搞反射太麻烦了,而且一点用都没有?”对于这个问题,我觉得有需要看框架的应该得懂,因为框架有用到,虽然我还没有学习,但在网上看到过这方面问答,所以就冒昧写出来了


二、基础知识

2.1 通过反射得到className的方式
		class.forName()
		类.class()方法
		实例化的类.getClass()方法
	
2.2 通过ClassName实例化对象的方式
		通过class的newInstance的方法
		通过Constructor来创建
		他们的区别在于,前者只能实例化无参的实例化对象,后者兼容各种参数的实例化对象,当然还包括无参的
	
2.3 常用类
		Method跟类的方法挂钩
		Field跟类的字段挂钩
		Constructor跟类的构造方法挂钩
	
2.4 常用方法
		Method.getMethod()获取public的类方法,局限性很大
		Method.getDeclaredMethod()使用方法跟上面一样,但除了public方法,还可以获取private方法
		如果你尝试使用getMethod()方法来获取private方法,那么将会提示你NoSuchMethodException()
		其余的Field方法同上

、具体实例

实现功能:访问类的私有方法,并将值打印出来

提供私有方法的类

public class BeiTest1 {
	public int myself=12;
	
	private int getchina(){
		return myself;
	}
}

操作类


public class ReflectTest1 {
	public static void main(String[] args) throws Exception{
		BeiTest1 test=new BeiTest1();
		//在这里可以使用newInstance或者Constractor来创建实例
		Class<?> classType=test.getClass();
		//使用getMethod将不能访问private方法,如果访问了将会抛出java.lang.NoSuchMethodException异常,后续也就得不到运行
		Method method=classType.getDeclareMethod("getchina",new Class[]{});
		//设置是否启用访问检测,如果为true则表示不检测,也就表示可以访问
		method.setAccessible(true);
		Integer aaa=(Integer)method.invoke(test, new Object[]{});
		System.out.println("结果是"+aaa);
	}
}

实现功能:将某个对象中的字段提取出来,保存到另外一个新建对象中,然后打印出来


class BeiTestCopy{
	int age;
	String name;
	
	public BeiTestCopy(int a,String n) {
		this.age=a;
		name=n;
	}
}


具体操作类

public class ReflectCopyTest {
	public static void main(String[] args) throws Exception{
		//模拟初始化对象
		BeiTestCopy testcopy=new BeiTestCopy(35,"张三");
		//调用函数,将通用的Object强转
		BeiTestCopy mycopy=(BeiTestCopy) copyObject(testcopy);
		//打印copy回来的数据
		System.out.println(mycopy.name+"今年"+mycopy.age);
	}
	public static Object copyObject(Object o) throws Exception{
		//获取对象中的各个字段的值
		Class<?> classType=o.getClass();
		//注,千万要使用declaredFields而非getfields方法,否则无返回
		Field[] fields=classType.getDeclaredFields();
		//用来存读取到的内容
		Object[] obj=new Object[2];
		int i=0;
		for(Field field:fields){
			//获取到对应字段的名称
			//System.out.println(field.getName());
			//field.get接的参数是要提取数据的实例,而非字段名称
			//System.out.println("找到的值"+field.get(o));
			obj[i]=field.get(o);
			i++;
		}
		
		//创建对象
		Class<?> classType2=o.getClass();
		Constructor<?> constructor=classType2.getConstructor(new Class[]{int.class,String.class});
		//直接使用先前存放的obj数组即可,以形成通用模式
		//Object newobj=constructor.newInstance(new Object[]{});
		Object newobj=constructor.newInstance(obj);
		//将新创建的对象返回出去
		return newobj;
	}
}


 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值