第21天 反射

反射概述

想象一下,你在一个房间里边,但你看不见自己,也不知道自己是谁。这时候你面前有一个镜子,你可以通过镜子的反射来观察自己。反射就像这面镜子。它让你能够检查、分析、修改Java中的对象、类、方法等

使用情况:在通常情况下,我们编写的代码是固定的,执行的结果也是固定的。但是某些情况下我们不确定要创建什么类型的对象,也不确定要调用什么类型的方法。这些都通过运行时传递的参数决定。该机制叫做动态编程技术,也就是反射机制

反射就是在程序运行 过程中,对于任意一个类,都能知道这个类所有的属性和方法。对于任意一个对象,都能调用它的所有属性和方法。也就是可以动态创建对象并且动态调用方法的机制

三步

创建字节码文件对象 forName .class .getClass
调用对应类的构造方法 getConstructor
调用构造方法创建对象 newInstance

类:Class
构造方法:Constructor
方法:Method
字段:Field (属性)
实例:Instance
执行:Invoke

获取class对象的三种方式

想象一下你如何获得iphone手机的图纸

  1. 先找到一个iphone实体,然后逆向拆解绘制出图纸 这相当于对象.getClass() 需要先找到类new出来对象
  2. 直接向苹果公司索要 这相当于类名.class
  3. 从苹果公司偷 这相当于Class.forName(“包名.类名”)

第三种方法可以降低耦合度,我获得图纸和苹果公司无关,反射的类名即使不存在也不会报错,方便后期更改
对象.class获取对应的Class对象,如果不是对象.class就没有对应的Class对象

  1. 使用类名.class的方式可以获取对应类型的Class对象

可以是引用数据类型,包括数组、类、接口等,也可以是基本数据类型

当使用打印int.class时,int.class 实际上返回的是 Class 对象,但在打印时,会自动调用 toString() 方法将其转换为字符串,输出基本数据类型的名称。这是 Java 语言的一种语法糖,使得基本数据类型和引用数据类型在某些场景下可以统一对待。

在命令行中打印一个类的 Class 对象时,Java 解释器会将该对象的 toString() 方法调用,并打印其返回的字符串。在 Class 类中,toString() 方法返回的是该类的全限定名,即包名加类名。
在反射中,引用数据类型的 Class 对象可以用于创建实例、调用方法等操作,而基本数据类型的 Class 对象则无法直接进行实例化和方法调用

Class<Integer> integerClass = Integer.class;
sout(integerClass);

sout(Integer.class);



  1. 使用字符串Class.forName(“字符串”)的方式来获取参数指定类型的Class对象

字符串需要是全路径名(包名.类名)

Class aclass2 = Class.forName("java.long.String");
sout(aclass2);

  1. 使用引用/对象.getClass()方式可以获取对象运行时的类信息

这里的对象需要首先创建出来再使用,打印出来的是创建出对象的引用类型变量的包名+类名

List list = new ArrayList();
sout(list.getClass());

Class类的方法

  1. static Class<?>forName(String className)
    用于获取参数指定对象的Class对象并返回
  2. T newInstance()
    用于创建该Class对象表示类的新实例。就是创建了一个对象
//以无参对象创建构造Person类对象并打印
 Class c1 = Class.forName("Person");//双引号中Person的值可以在运行中替换
 System.out.println("无参方式创造的对象是:"+c1.newInstance());

获取单个指定的构造方法

Constractor类

java.lang.reflect.Contractor类 主要用于描述获取到的构造方法信息

Class类的常用方法

Constructor getConstructor(Class<?>…parameterTypes):获取此Class对象所表示的公共构造方法。其中参数可以有或者没有。括号必须内是Class类型,基本数据类型.class获得

Constructor<?>[] constructors = aclass.getConstructors() : 获取此Class对象所表示的所有公共构造方法

Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors():获取此Class对象所表示的所有构造方法

Constractor类的常用方法

T newlnstance(Onject…initargs) 使用此Constructor对象描述的构造方法来构造Class对象代表类型的新实例,给构造方法传参数,可以不传或者传多个。



获取属性

Field field = 字节码文件.getField
field.set(要赋值的对象,赋值给对象的值)
Object o = filed.get(类的名字)

获取方法

Method method = 字节码文件.getMethod(“方法名字”,需要方法的参数,class)
Object invoke = method.invoke(传的参数,又传的参数)

.class和.Class的区别

.class :创建对象的包装类,可以创建一个Class对象
int.class:就是int类型的Class对象引用,不是一个类,是一个引用,int类型是原始类型,用于获取基本数据类型int的Class对象
Integer是int类型的包装类,不是一个引用

.Class :用于返回对象的运行时的类的引用,表示某个对象的实际类型,用于获取某个对象的类信息

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值