本帖最后由 qianji20000420 于 2017-8-5 22:33 编辑

导读

  • 获取class文件对象的三种方式
  • 通过反射调用无参构造并使用
  • 通过反射调用含参构造并使用
  • 通过反射调用私有构造方法并使用(更改访问权限调用) 及对IllegalAccessException的讲解



获取class文件对象的三种方式

  • 什么是class文件对象?

在第一篇已经讲了,Java在加载类时会创建一个与该类对应的字节码文件对象,这个对象是Class类的一个实例
  • 关于CLass类

先上一波API

可能大家对Class这个类不算太熟悉。但是Class这个名并不是第一次见。

这个是Object类的getClass方法 可能你并没有用到过。 但是今天反射却要用到他了
这就是我们获取class文件对象的一种方式。
  • 下面为大家总结一下获取class文件对象的三种方式

  • 当想要获取一个对象或实例或字段的class文件对象 需要用到Object类的getClass()方法
  • 当想要获取一个类的class文件对象 使用 类名.class 来获取
  • Class类提供了forName方法 传入类的全路径来获取



通过反射调用无参构造并使用


这里我们先创建两个类 Demo 和 test 在test里我已经写好了无参构造 在Demo里我已经写好了主方法
接下来在主方法中获取test类的字节码文件对象
  1. Class c = test.class;
复制代码
然后通过查询API得知:

这四个方法是与构造方法有关的
有没有getConstructor和getDeclaredConstructor的区别在于有Declared能获取到非公共的即无public修饰的构造方法
接下来我会使用getDeclaredConstructor()  ps:反正带Declared的都能获取到 何乐而不为呢?(啪)
接下来在主方法中写上
  1. Constructor cs = c.getDeclaredConstructor();
复制代码
getDeclaredConstructor的参数是Class类实例。也就是构造函数中参数所对应的Class对象,因为是无参的,所以这里空就可以了。
Constructor的泛型先不用管它了。
发现有异常了。 不管他先抛出 等会再讲

这样就获取到了test类的无参构造对应的Constructor对象
接下来我们要用到Constructor类下的newInstance方法 参数即为构造函数的参数

这个方法的用途和 new 的用途基本相同
也就是说在这里
cs.newInstance() 与 new test() 是等价的
  1. test t = (test) cs.newInstance();
复制代码
之后我们将获取到的对象直接强转为test就获取到test的对象了
控制台就会输出个hi 证明我们成功通过反射成功调用了test的无参构造并实例化了对应的test对象

通过反射调用含参构造并使用

用法和无参基本相同,只需要在getDeclaredConstructor及newInstance后面的参数做变化
getDeclaredConstructor的参数是class文件对象,也就是说 他应该传入的是对于构造函数参数所对应类的对应Class对象
这里应该用String.class
newInstance后面的参数即为你实例化一个对象传入构造函数中的参数

调用私有构造方法

当我们在test类中创建一个私有的构造函数
比如

然后在主方法中 将“233”随便改成一个int类型的数 我这里比如123
并把String.class改成int.class (基本数据类型也有对应的class对象哦)

当我们运行时

怎么报错了??!
IllegalAccessException 正如名字一样  非法的访问异常
他既然是私有的,能让你轻易访问吗?
这时我们看到了--


我天,这不就容易了。 我来


所以说 , 私有的构造方法不是不能够被调用的。。


下一篇

反射中对成员变量的调用
返回索引贴
第一次做教程,如果教程中有遗漏的或说错的地方请及时指出哇。~
[groupid=1181]Unknown Domain[/groupid]