分享

【Java】基础51:反射(一)

 刘小爱v 2020-06-04

今天是刘小爱自学Java的第51天。

感谢你的观看,谢谢你。

话不多说,开始今天的学习:

Class对象是用来描述字节码文件(也就是class文件)

比如类、接口、枚举……等这些

一、Class对象

在Java中Class本身也就对应一个类,用来表示class文件,任何一个class文件都是Class类的一个对象

1Class对象的三种获取方式

①用类名直接调用

可以将其理解成类的一个静态属性,所以用类名可以直接调用。当然这样并不准确,但可以这样理解记忆。

②Class类的forName方法

Class中有个静态方法forName(),使用类名Class可以直接调用;参数为对应类的全限定名,也就是包名+类名。

③对象名调用getClass方法

任何一个对象,都有一个对应的class对象。

使用getClass方法即可以获取,其中数组也有对应的class对象。

2预定义对象

预定义主要就是指void和基本数据类型,这是在Java中已经定义好了的。

就好比买新手机后,也会有自带的各种系统软件一样。

①关键字 void 也有对应的Class 对象

void代表的是没有返回值类型,那么它也是一种数据类型,表示没有类型,那么输出对象也是void本身。

Class voidClass= void.class;对象voidClass中保存的就是void。

②基本数据类型

四类八种:boolean、byte、char、short、int、long、float,double。基本数据类型要保存在内存中,那么他们也会有自己的字节码。

获取的Class对象中保存的就是他们本身,因为基本数据类型不属于任何包下的。

如:Class c = int.class,对象c中保存的就是int。

总结言之:任何的一种数据类型都具有自己的Class对象

二、反射

反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖(主要用于框架中)。

类中有什么?

构造方法,成员方法,成员对象,我们来一一说明。

1构造器对象

常规方法创建对象我们常使用,直接new对象就好了。

我们今天学习的是利用反射创建对象:

①获取Class对象

Student类对应的Class对象sClass。

②获取构造器

Constructor,翻译过来就是构造器的意思,在Java中也是一个类。

sClass有一个方法叫getConstructor(),顾名思义,其作用就是获取一个构造器,无参数即对于空参构造。

③构造器创建对象

instance,翻译过来就是实例的意思,也就是说newInstance就是将类实例化,对象就是类的实例化。

那么现在问题来了:

我明明一行代码就可以创建对象,使用反射的话要三行代码,这不是越弄越复杂么?

老实说我也是这么觉得的,不过反射一般应用于框架,既然能应用于框架,肯定有其牛逼之处。

说一个简单的特别之处:

当构造方法为私有的时候,是没法直接new对象的,但是反射可以:

①获取所有声明的构造

Declared,翻译过来就是声明的意思,也就是说只要是声明的方法,类对应的Class对象都可以获取。

  • getConstructor:只能获取public修饰的构造。

  • getDeclaredConstructor:能获取所有声明的构造。

现在能获取了,但是打印的话还是会报错,这是为什么?

这就好比私有构造方法就相当于在构造器上锁了一把锁;

如果是常规方法创建对象,连这个构造器都拿不到。

现在用getDeclaredConstructor拿到这个构造器了,但是一看构造器上有锁,还是没法创建对象,那该怎么办?

②修改权限

构造器有一个方法,叫setAccessible()。Accessible,翻译过来就是可取得的,当参数为true时,也就是说可以取得了。

这很好理解,就相当于把锁给打开了。

2方法对象

①getMethod()方法

顾名思义,这就是一个获取类中成员方法的方法。

该方法有两个参数:

  • String name

  • Class<?>... parameterTypes

第一个参数为方法名,第二个参数为参数类型;

也就是说根据方法名和参数类型,就可以找到类中对应的成员方法。

②invoke方法

invoke,翻译过来就是调用的意思。

同样该方法也有两个参数:

  • Object object:调用方法的对象

  • Object…args:该对象调用方法时的参数

第一个参数为谁调用该方法,第二个参数为该方法参数。

show.invoke(stu,"刘小爱")相当于:stu.show("刘小爱")

同样的道理,反射也可以访问私有方法:

①getDeclaredMethod方法

  • getMethod:只能获取public修饰的方法。

  • getDeclaredMethod:能获取所有声明的方法。

再调用setAccessible()方法设置权限,参数设为true,即可以访问私有方法了。

3属性对象

①getField方法

顾名思义,获取属性,参数即为属性名。

也就是根据类中的属性名,我们就能找到类中对应的成员变量。

②set方法

设置属性方法,有两个参数:

  • Object obj:属性所关联的对象

  • Object value:参数

name.set(stu,"刘小爱"),也就相当于stu.setName(value)

将stu对象中的name属性设定为“刘小爱”。

③get方法

获取stu对象中的name属性。

同样的道理,反射也可以获取私有属性

①访问私有属性

同样的道理

  • getField:只能获取public修饰的属性。

  • getDeclaredField:能获取所有声明的属性。

再调用setAccessible()方法设置权限,参数设为true,即可以访问私有属性了。

总结:

谢谢你的观看。

如果可以的话,麻烦帮忙点个赞,谢谢你。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多