Java之反射机制

反射机制

引出反射

在这里插入图片描述
我们的猫类
在这里插入图片描述

传统的方式
就是new 然后通过对象调用呗
在这里插入图片描述
用properties做的话,首先肯定是获取信息
读取配置文件的信息
在这里插入图片描述
然后我们需要创建对象是吧
但是这个时候
new classfullpath是不行的,因为我们实际上需要的是
类名
而不是字符串,不能用字符串来代替类名
所以你从配置文件读取的信息,不能用来创建类
那该怎么办呢?
这就该用到反射了

反射快速入门

在这里插入图片描述
这样的意义就是通过外部文件配置在不修改源码来控制程序
是我们学习后面Spring全家桶,Mybaits等框架的灵魂

比如你的猫类里面多一个cry方法
你想调用cry不想调用hi就只能修改源码,把cat.hi改为cat.cry
而反射的话
在这里插入图片描述
只需要把method=hi改为method=cry就可以了,修改的是配置文件不是源代码

反射原理图

在这里插入图片描述
就是本质是通过Class类对象来操作对象
而反射就是
不通过new什么的
直接通过Class类来操作

而且对应的Class类存储的都是对象
可以把方法当做对象,构造器也可以当做对象,变量也是对象
每个对象存储在对应的对象数组里

反射机制中主要类

在这里插入图片描述
演示的话
在Cat类多加一个public属性age=10
在加一个构造器
在这里插入图片描述
变量获取
在这里插入图片描述

获取无参构造
在这里插入图片描述
获取有参构造
在这里插入图片描述

可以通过对应的

成员变量对象.get(对象)来获取对应的值
这个对象是我们cat的实例对象

方法上面也有例子
方法对象.invoke(对象)
关于方法为什么也要区别化,因为每个对象的属性值可能不一样,方法可能调用属性值,所以对应的方法也可能不一样,具体表现就是每个对象的方法对象不同

还有那个构造器
构造器对应的方法之后讲
无参和有参构造器
有参构造的话,他的参数不是什么String而是String.class就是String类的Class对象

代码

package yuan.hsp.reflection;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

import org.junit.jupiter.api.MethodOrderer.MethodName;
@SuppressWarnings({"all"})
//反射机制的简单介绍
public class introduce {
	public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, 
	IllegalAccessException, NoSuchMethodException, SecurityException, 
	IllegalArgumentException, InvocationTargetException, NoSuchFieldException {//这异常有点多,你忍一下
//	1.正常想调用对应的方法
//	Cat cat = new Cat();
//	cat.hi();
//	2.使用properties类,通过配置文件来进行对应方法的调用,先读取配置文件
		Properties properties = new Properties();
//		properties.load(new FileInputStream("d:\\eclipseworkspace\\Learn\\src\\re.properties"));
		properties.load(new FileInputStream("src\\re.properties"));
		String classfullpath = properties.get("classfullpath").toString();
		String Method = properties.get("method").toString();
		System.out.println(classfullpath);
		System.out.println(Method);
		
//		3.反射机制运用
		//1.加载类,返回Class对象cls
		Class cls = Class.forName(classfullpath);
		//2.通过cls创建对象实例
		Object newInstance = cls.newInstance();
		System.out.println(newInstance.getClass());
		//3.通过对cls来获取到我们对应的对象方法,在反射中万物皆是对象
		Method method1 = cls.getMethod(Method);
		//4.通过method1调用方法,调用格式:方法对象.invoke(实例对象)
		System.out.println("==============================");
		method1.invoke(newInstance);
		//好处就是可以通过该配置文件来改变调用方法,不用修改源代码
		
//		一些常用类的方法
		//java.lang.reflect.Field:代表类的成员变量,Field对象表示某个类的成员变量
		//得到age字段吧,因为private的name是无法用getField获取
		Field field = cls.getField("age");
		System.out.println(field.get(newInstance));//成员变量对象.get(实例对象)
		
		Constructor constructor = cls.getConstructor();
		System.out.println(constructor);
		
		Constructor constructor2 = cls.getConstructor(String.class);
		System.out.println(constructor2);
		
		
	}
}

反射优化

在这里插入图片描述

案列演示

package yuan.hsp.reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@SuppressWarnings({"all"})
//演示类罢了
//还有一个时间对比来进行反射的优化
public class Cat {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, 
	IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, 
	InvocationTargetException {
		Cat cat = new Cat();
		cat.m1();
		cat.m2();
		cat.m3();
		
	}
	
	//这里为了方便我们观察,把hi()输出的内容注释
	//m1是普通的对象调用方法
	//m2就是用反射机制调用方法,取消访问调查
	//m3没有调用setAccessible(true),没有取消访问调查
	//可以发现效率差距很大,怎么进行优化呢?
	public void m1() {
		Cat cat = new Cat();
		long start = System.currentTimeMillis();
		for(int i =0;i<900000000;i++) {
			cat.hi();
		}
		long end = System.currentTimeMillis();
		System.out.println("m1耗时"+(end-start));
	}
	public void m2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, 
	NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		Class cls = Class.forName("yuan.hsp.reflection.Cat");
		Object cat = cls.newInstance();
		Method method = cls.getMethod("hi");
		method.setAccessible(true);//取消访问检查,提高效率
		
		
		
		long start = System.currentTimeMillis();
		for(int i =0;i<900000000;i++) {
			method.invoke(cat);
		}
		long end = System.currentTimeMillis();
		System.out.println("m2=耗时"+(end-start));
		
	}
	public void m3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, 
	NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		Class cls = Class.forName("yuan.hsp.reflection.Cat");
		Object cat = cls.newInstance();
		Method method = cls.getMethod("hi");
			
		long start = System.currentTimeMillis();
		for(int i =0;i<900000000;i++) {
			method.invoke(cat);
		}
		long end = System.currentTimeMillis();
		System.out.println("m3=耗时"+(end-start));
		
	}
	
	private String name="招财猫";
	public int age =10;
	

	public Cat() {
		super();
	}
	public Cat(String name) {
		super();
		this.name = name;
	}
	public void hi() {
//		System.out.println("hi"+name);
	}
	public void cry() {
		System.out.println(name+"喵喵叫...");
	}
}

在这里插入图片描述

优化方法

在这里插入图片描述

可以通过设置为true来跳过访问调查这个步骤提高效率
就是我们之前代码的m2()和m3()对比
多出来那一行代码

method.setAccessible(true);//取消访问检查,提高效率

可以一定程度上提高效率,但是肯定不如传统方式来的快

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小袁拒绝摆烂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值