目录
- 什么是反射
- 具体用法
什么是反射
面向对象中有一个概念叫封装,我们在编写类的时候会给一些不需要外界调用的字段
private
修饰,就好比在黑暗里有人在走你看不见,但是用了反射,就像在阳光下拿镜子将阳光反射到了黑暗里的人身上,能够完全获取
运行时
类的信息,即使这个信息是
private
的。
C++中的RTTI和Java反射完全不能比,C++反射需要自己去实现,比较复杂,Java提供了API供使用者调用
什么时候使用反射呢?很多时候我们没法确定程序在编写的时候要用到哪些类,比如现在有这样的需求:
从键盘输入一个字符串,输入什么就创建什么类的实例。比如输入Human,就需要在程序中构造一个Human的对象。这样就和我们在面向对象里的
new Human()
完全不一样了。使用new是因为我们预先知道需要什么实例,但是这个需求里我们没有办法知道要用什么实例。
再说一个经典应用场景,通过
url
访问
Tomcat
,
tomcat
不知道你会发送什么
url
,如果发送的是
login
,
tomcat
会用
login
反射创建
Login
的
Servlet
,进而运行
Login
的逻辑
具体用法
对于任何一个类,都是一个Class类,比如Food类,其Class类就是对Food的抽象,直接看代码
这里的
class1
就是
Persion
这个类的Class实例。接着通过class1的一些接口,我们可以拿到运行时,Persion的所有属性,构造器,方法。
Class class1=Persion.class;
Constructor constructor=class1.getConstructor(String.class,int.class); //这里拿到了Persion的构造器
Persion obj=(Persion)constructor.newInstance("Tom",14); //通过构造器构造了一个名字叫Tom 年龄是14的人
System.out.println(obj.toString());
Field age = class1.getDeclaredField("age"); //这里拿到的是Persion的属性age
age.set(obj,10);
System.out.println(obj);
Method show = class1.getDeclaredMethod("show"); //Persion的方法show
show.invoke(obj);
Constructor declaredConstructor = class1.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
Object jerry = declaredConstructor.newInstance("Jerry");
System.out.println(jerry);
Field name = class1.getDeclaredField("name");
name.setAccessible(true); //通过设置setAccessible(true)可以访问一些private的属性。
name.set(obj,"hanmemei");
System.out.println(obj);