首先,看一下反射最重要的四句代码:

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、反射是否破坏了封装性?

通过上面的反射访问一个类的内部私有属性,方法等,貌似与封装性想违背,封装性有私有和共有来保证代码的安全性,在外部调用共有方法。反射最大的特点是动态性,解决的是能不能调用的问题,可以调用私有方法,但是平时不建议调用。所以两者并不冲突。

【回炉重造】——反射相关推荐

  1. Vue回炉重造之封装防刷新考试倒计时组件

    你好,我是Vam的金豆之路,可以叫我豆哥.2019年年度博客之星.技术领域博客专家.主要领域:前端开发.我的微信是 maomin9761,有什么疑问可以加我哦,自己创建了一个微信技术交流群,可以加我邀 ...

  2. 机器人学回炉重造(1-2):各种典型机械臂的正运动学建模(标准D-H法)

    文章目录 写在前面 三连杆平面机械臂 平行四边形操作臂 闭链结构 例:平行四边形操作臂 球形臂 拟人臂 球腕 斯坦福机械臂 带球形手腕的拟人化机械臂 DLR机械臂 参考文献 写在前面 本文所有机械臂均 ...

  3. 《回炉重造 Java 基础》——集合(容器)

    整体框架 绿色代表接口/抽象类:蓝色代表类. 主要由两大接口组成,一个是「Collection」接口,另一个是「Map」接口. 前言 以前刚开始学习「集合」的时候,由于没有好好预习,也没有学好基础知识 ...

  4. 机器人学回炉重造(5-2):关节空间规划方法——梯形加减速(与抛物线拟合的线性函数)、S型曲线规划

    文章目录 写在前面 学习代码都记录在[个人github](https://github.com/xuuyann/RobotLearningCode)上,欢迎关注~ 梯形加减速(与抛物线拟合的线性函数) ...

  5. 真人电影中的幻想生物迷墙:索尼克为什么被骂到回炉重造?

    <大侦探皮卡丘>上映在即,当网友们对着雷佳音配音的皮卡丘大呼好萌好萌时,我们仿佛又来到了大型真香现场--明明在几个月之前,当人们看到毛茸茸的大叔音皮卡丘时还每个细胞都充满了拒绝. 也有一种 ...

  6. 机器人学回炉重造(2-4):运动学奇异位型分析

    文章目录 什么是运动学奇异位型? 例子:平面二连杆机械手的奇异位型 奇异位型解耦 腕部奇异位型 手臂奇异位型 转载:6轴串联关节机器人的奇异点 参考文献 什么是运动学奇异位型? 在初步系统地了解了机器 ...

  7. Vue回炉重造之封装一个实用的人脸识别组件

    你好,我是Vam的金豆之路,可以叫我豆哥.2019年年度博客之星.技术领域博客专家.主要领域:前端开发.我的微信是 maomin9761,有什么疑问可以加我哦,自己创建了一个微信技术交流群,可以加我邀 ...

  8. 机器人学回炉重造(2-3):基本雅可比矩阵与其他雅可比矩阵

    文章目录 基本雅可比矩阵 定义 求法 其他雅可比矩阵 定义 求法 补充:几何雅可比与解析雅可比 基本雅可比矩阵 定义 用笛卡尔坐标描述线速度(linear velocity)和角速度(angular ...

  9. 回炉重造之数据结构【一】基本概念

    回炉重造之数据结构[一]绪论 文章目录 回炉重造之数据结构[一]绪论 数据结构的基本概念 基本概念和术语 数据结构的三要素 算法和算法评价 算法的基本概念 算法效率的度量 数据结构的基本概念 基本概念 ...

  10. javacript回炉重造之基础细节点

    ascript之回炉重造 var n5=2e5 2*10的五次方 0x开头十六进制 0o开头八进制 0b开头二进制 typeof 用于检测数据类型 值类型(基本类型):字符串(String).数字(N ...

最新文章

  1. pytorch nan问题
  2. 多用户虚拟Web3D环境Deep MatrixIP9 1.04发布
  3. Java中数组的length属性
  4. 单调队列优化多重背包
  5. Java面试题及答案2020,java数组循环赋值
  6. opencv运动目标跟踪预测_基于Opencv的运动目标的检测和跟踪.pdf
  7. 卵巢鸿蒙不全怎么检查,卵巢黄体功能不足怎么办 这三个处理方法要了解
  8. 亚信安全携五大创新安全方案,发布AI²亚信安全智能框架
  9. 编译并运行Java文件
  10. 【原生JavaScript案例】原生JS实现进度条
  11. 天地不仁,以万物为刍狗
  12. 问题解决——WSAAsyncSelect模型 不触发 FD_CLOSE
  13. Tcl/Tk--文件操作
  14. 支付宝、微信后台不死的黑科技
  15. 图形学扫描线填充算法
  16. jsp使用URLRewrite实现url地址伪静态化
  17. udp2raw android,关于udpspeeder和udp2raw部署的一些补充,及使用体会
  18. SpringBoot25-spingboot数据访问-数据缓存Cache
  19. 你以为SSL是安全的吗?
  20. spring-boot-starter 自定义

热门文章

  1. C语言 qsort的用法 模拟EXCEL排序
  2. BZOJ3730 震波+BZOJ4372 烁烁的游戏(动态点分治)
  3. javascript百炼成仙 第一章 掌握JavaScript基础01 初入宗门
  4. flume 从基础到高阶
  5. 基于java的俄罗斯方块小游戏设计(含源文件)
  6. java中使用javac编译时报错:未报告的异常 必须对其进行捕捉或声明以便抛出
  7. Asciinema终端SSH录屏神器使用
  8. 《labuladong的算法小抄》| 笔记
  9. 基础30讲 第11讲 多元函数微分学
  10. 时间子系统10_hpet时钟初始化