【回炉重造】——反射
首先,看一下反射最重要的四句代码:
package com.wu.test01;/*** @author wu* @version 2022/1/18 10:35 PM*/
public class AliPay implements Mtwm {@Overridepublic void payOnline() {//具体的支付宝支付:System.out.println("我已经点了外卖,我正在使用支付宝进行支付" );}
}public static void main(String... args) throws Exception {//定义一个字符串,用来模拟前台的支付方式:String str = "com.wu.test01.AliPay";//下面的代码就是利用反射Class cls = Class.forName(str);Object o = cls.newInstance();Method method = cls.getMethod("payOnline");method.invoke(o);
}
什么是反射?
然后,反射的定义是:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能成为java语言的反射机制。
反射可以用来做什么
反射所体现的就是一种动态性,就像一个镜子,通过反射的api获取一个类内部的所有内部信息。这也是我认为它叫反射的一个含义。
1、获取构造器和创建对象
public static void main(String... args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取字节码信息Class cls = Student.class;//通过字节码信息可以获取构造器//getConstructors只能获取当前运行时类的被public修饰的构造器Constructor[] c1 = cls.getConstructors();for (Constructor c : c1) {System.out.println(c);}System.out.println("------------------");//getDeclaredConstructors:获取运行时类的全部修饰符的构造器Constructor[] c2 = cls.getDeclaredConstructors();for(Constructor c:c2){System.out.println(c );}System.out.println("------------------");//获取指定的构造器//得到空构造器Constructor con1 = cls.getConstructor();System.out.println( con1);//得到两个参数的有参构造器Constructor con2 = cls.getConstructor(double.class, double.class);System.out.println(con2);//得到一个参数的有参构造器:并且是private修饰的Constructor con3 = cls.getDeclaredConstructor(int.class);System.out.println(con3);//有了构造器以后我就可以创建对象Object o1 = con1.newInstance();System.out.println(o1);Object o2 = con2.newInstance(180.5, 170.6);System.out.println(o2);}
2、获取属性和对属性赋值
public static void main(String... args) throws NoSuchFieldException, IllegalAccessException, InstantiationException {//获取运行时类的字节码信息Class cls = Student.class;//获取属性//getFields:获取运行时类和父类中被public修饰的属性Field[] fields = cls.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("--------------");Field[] declaredFields = cls.getDeclaredFields();for (Field field : declaredFields) {System.out.println(field);}System.out.println("--------------");//获取指定的属性Field score = cls.getField("score");System.out.println(score);Field sno = cls.getDeclaredField("sno");System.out.println(sno);System.out.println("--------------");//属性的具体结构://获取修饰符int modifiers = sno.getModifiers();System.out.println(modifiers);System.out.println(Modifier.toString(modifiers));System.out.println(Modifier.toString(sno.getModifiers()));//获取属性的数据类型Class clazz = sno.getType();System.out.println(clazz.getName());//获取属性的名字String name = sno.getName();System.out.println(name);System.out.println("--------------");//给属性赋值:(给属性设置值,必须要有对象)Field sco = cls.getField("score");Object obj = cls.newInstance();sco.set(obj, 98);System.out.println(obj);}
3、获取方法和调用方法
public static void main(String... args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {//获取字节码信息Class cls = Student.class;//获取方法://getMethods:获取运行时类的方法还有所有父类中的方法(被public修饰)Method[] methods = cls.getMethods();for (Method m : methods) {System.out.println(m);}System.out.println("----------------" );//:获取运行时类中的所有方法Method[] declaredMethods = cls.getDeclaredMethods();for (Method m : declaredMethods) {System.out.println(m);}System.out.println("----------------");//获取指定的方法:Method showInfo1 = cls.getMethod("showInfo");System.out.println(showInfo1);Method showInfo2 = cls.getMethod("showInfo", int.class, int.class);System.out.println(showInfo2);Method work = cls.getDeclaredMethod("work",int.class);System.out.println(work);System.out.println("----------------");//获取方法的具体结构:/*@注解修饰符 返回值类型 方法名(参数列表) throws XXXX{}*///名字System.out.println(work.getName());//修饰符int modifiers = work.getModifiers();System.out.println(Modifier.toString(modifiers));//返回值System.out.println(work.getReturnType());//参数列表Class[] parameterTypes = work.getParameterTypes();for (Class c:parameterTypes){System.out.println(c);}//获取注解Method myMethod = cls.getMethod("myMethod");Annotation[] annotations=myMethod.getAnnotations();for (Annotation a:annotations){System.out.println(a);}//获取异常Class[] exceptionTypes = myMethod.getExceptionTypes();for (Class c:exceptionTypes){System.out.println(c);}//调用方法Object o=cls.newInstance();myMethod.invoke(o);System.out.println(showInfo2.invoke(o,12,45));}
4、获取类的接口,所在包,注解
public static void main(String... args) {//获取字节码信息Class cls = Student.class;//获取运行时类的接口Class[] interfaces = cls.getInterfaces();for (Class c : interfaces) {System.out.println(c);}//得到父类的接口//先得到父类的字节码信息Class superclass = cls.getSuperclass();//得到接口Class[] interfaces1 = superclass.getInterfaces();for (Class c : interfaces1) {System.out.println(c);}//获取运行时类所在的包Package aPackage = cls.getPackage();System.out.println(aPackage);System.out.println(aPackage.getName());//获取运行类的注解Annotation[] annotations = cls.getAnnotations();for (Annotation a : annotations) {System.out.println(a);}}
反射相关类
Class类
方法 | 说明 |
getClassLoader() | 获得类的加载器 |
forName(String className) | 根据类名返回类的对象 |
getName() | 获得类的完整路径名字 |
newInstance() | 创建类的实例 |
getPackage() | 获得类的包 |
getSuperclass() | 获得当前类继承的父类的名字 |
getInterfaces() | 获得当前类实现的类或是接口 |
Field类
方法 | 说明 |
getField(String name) | 获得公有的属性对象 |
getFields() | 获得所有公有的属性对象 |
getDeclaredFields() | 获得所有属性对象 |
getDeclaredField(String name) | 获得某个属性对象 |
Method类
方法 | 说明 |
getAnnotation(Class<A> annotationClass) | 返回该类中与参数类型匹配的公有注解对象 |
getAnnotations() | 返回该类所有的公有注解对象 |
getDeclaredAnnotation(Class<A> annotationClass) | 返回该类中与参数类型匹配的所有注解对象 |
getDeclaredAnnotations() | 返回该类所有的注解对象 |
Constructor类
方法 | 说明 |
getConstructor(Class...<?> parameterTypes) | 获得该类中与参数类型匹配的公有构造方法 |
getConstructors() | 获得该类的所有公有构造方法 |
getDeclaredConstructor(Class...<?> parameterTypes) | 获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() | 获得该类所有构造方法 |
反射通过字节码信息获取类,获取公共方法属性的,还可以获取私有、保护等信息。那么就引出两个问题:
两个问题
1、创建一个对象,是用new Person() 还是利用反射?
建议使用new的方式,因为这样在编译的时候就确定了要初始化的对象,而不是等到运行时。那我们什么时候用反射呢?就是不确定要new哪个对象的时候,在运行时来决定,这就体现了反射的动态性。
2、反射是否破坏了封装性?
通过上面的反射访问一个类的内部私有属性,方法等,貌似与封装性想违背,封装性有私有和共有来保证代码的安全性,在外部调用共有方法。反射最大的特点是动态性,解决的是能不能调用的问题,可以调用私有方法,但是平时不建议调用。所以两者并不冲突。
【回炉重造】——反射相关推荐
- Vue回炉重造之封装防刷新考试倒计时组件
你好,我是Vam的金豆之路,可以叫我豆哥.2019年年度博客之星.技术领域博客专家.主要领域:前端开发.我的微信是 maomin9761,有什么疑问可以加我哦,自己创建了一个微信技术交流群,可以加我邀 ...
- 机器人学回炉重造(1-2):各种典型机械臂的正运动学建模(标准D-H法)
文章目录 写在前面 三连杆平面机械臂 平行四边形操作臂 闭链结构 例:平行四边形操作臂 球形臂 拟人臂 球腕 斯坦福机械臂 带球形手腕的拟人化机械臂 DLR机械臂 参考文献 写在前面 本文所有机械臂均 ...
- 《回炉重造 Java 基础》——集合(容器)
整体框架 绿色代表接口/抽象类:蓝色代表类. 主要由两大接口组成,一个是「Collection」接口,另一个是「Map」接口. 前言 以前刚开始学习「集合」的时候,由于没有好好预习,也没有学好基础知识 ...
- 机器人学回炉重造(5-2):关节空间规划方法——梯形加减速(与抛物线拟合的线性函数)、S型曲线规划
文章目录 写在前面 学习代码都记录在[个人github](https://github.com/xuuyann/RobotLearningCode)上,欢迎关注~ 梯形加减速(与抛物线拟合的线性函数) ...
- 真人电影中的幻想生物迷墙:索尼克为什么被骂到回炉重造?
<大侦探皮卡丘>上映在即,当网友们对着雷佳音配音的皮卡丘大呼好萌好萌时,我们仿佛又来到了大型真香现场--明明在几个月之前,当人们看到毛茸茸的大叔音皮卡丘时还每个细胞都充满了拒绝. 也有一种 ...
- 机器人学回炉重造(2-4):运动学奇异位型分析
文章目录 什么是运动学奇异位型? 例子:平面二连杆机械手的奇异位型 奇异位型解耦 腕部奇异位型 手臂奇异位型 转载:6轴串联关节机器人的奇异点 参考文献 什么是运动学奇异位型? 在初步系统地了解了机器 ...
- Vue回炉重造之封装一个实用的人脸识别组件
你好,我是Vam的金豆之路,可以叫我豆哥.2019年年度博客之星.技术领域博客专家.主要领域:前端开发.我的微信是 maomin9761,有什么疑问可以加我哦,自己创建了一个微信技术交流群,可以加我邀 ...
- 机器人学回炉重造(2-3):基本雅可比矩阵与其他雅可比矩阵
文章目录 基本雅可比矩阵 定义 求法 其他雅可比矩阵 定义 求法 补充:几何雅可比与解析雅可比 基本雅可比矩阵 定义 用笛卡尔坐标描述线速度(linear velocity)和角速度(angular ...
- 回炉重造之数据结构【一】基本概念
回炉重造之数据结构[一]绪论 文章目录 回炉重造之数据结构[一]绪论 数据结构的基本概念 基本概念和术语 数据结构的三要素 算法和算法评价 算法的基本概念 算法效率的度量 数据结构的基本概念 基本概念 ...
- javacript回炉重造之基础细节点
ascript之回炉重造 var n5=2e5 2*10的五次方 0x开头十六进制 0o开头八进制 0b开头二进制 typeof 用于检测数据类型 值类型(基本类型):字符串(String).数字(N ...
最新文章
- pytorch nan问题
- 多用户虚拟Web3D环境Deep MatrixIP9 1.04发布
- Java中数组的length属性
- 单调队列优化多重背包
- Java面试题及答案2020,java数组循环赋值
- opencv运动目标跟踪预测_基于Opencv的运动目标的检测和跟踪.pdf
- 卵巢鸿蒙不全怎么检查,卵巢黄体功能不足怎么办 这三个处理方法要了解
- 亚信安全携五大创新安全方案,发布AI²亚信安全智能框架
- 编译并运行Java文件
- 【原生JavaScript案例】原生JS实现进度条
- 天地不仁,以万物为刍狗
- 问题解决——WSAAsyncSelect模型 不触发 FD_CLOSE
- Tcl/Tk--文件操作
- 支付宝、微信后台不死的黑科技
- 图形学扫描线填充算法
- jsp使用URLRewrite实现url地址伪静态化
- udp2raw android,关于udpspeeder和udp2raw部署的一些补充,及使用体会
- SpringBoot25-spingboot数据访问-数据缓存Cache
- 你以为SSL是安全的吗?
- spring-boot-starter 自定义