一、定义
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
二、作用,为什么?
- 编码提示 、解耦;
- class设计原则:开闭原则,7大设计原则最重要的原则。
三、类的生命周期
源代码–>*.class --> Class对象(类加载器)—>构造Object(Runtime)—>垃圾回收。
Class对象:field对象,method对象,constructor对象
四、使用
1. Class对象
Class aClass = Class.forName("com.company.pojo.User");
System.out.println(aClass);
Class bClass = User.class;
System.out.println(bClass);
User user = new User();
Class cClass = user.getClass();
System.out.println(cClass);
获取CLASS对象三种方法:
1)Class.forName("全路径类名")
源代码获取
2)类名.class
3)对象.getClass()
运行时,有class对象了
2. Class对象功能:
1)获取成员变量
2)获取构造方法
3)获取成员方法
4)获取类名,包名
代码演示说明:
public class Main {
public static void main(String[] args) throws Exception{
// write your code here
Class aClass = Class.forName("com.company.pojo.User");
/* System.out.println(aClass);
Class bClass = User.class;
System.out.println(bClass);
User user = new User();
Class cClass = user.getClass();
System.out.println(cClass);*/
/* 获取方法
User user = new User();
Method login = aClass.getMethod("login");
Method loginB = aClass.getMethod("login",String.class);
login.invoke(user);
loginB.invoke(user,"zhangsan");*/
/* 获取所有方法
Method[] methods = aClass.getMethods();
for (Method m:methods){
System.out.println(m);
}*/
/* 暴力反射获取隐私方法
User user = new User();
Method loginOut = aClass.getDeclaredMethod("loginOut");
loginOut.setAccessible(true);
loginOut.invoke(user);*/
/*获取构造方法
Constructor[] constructors = aClass.getConstructors();
for (Constructor c:constructors) {
System.out.println(c);
}
Constructor constructor = aClass.getConstructor();
Object o = constructor.newInstance();
System.out.println(o);*/
/* 获取方法(执行)
User user = new User();
Field passwork = aClass.getDeclaredField("passwork");
passwork.setAccessible(true);
passwork.set(user,"12344");
Object o = passwork.get(user);
System.out.println(o);*/
}
}
2、Method
获取Method:
- getMethod(name,parameterType),getMethods()可以反射出原class的public方法
- getDeclaredMethod(),getDeclaredMethods()可以反射出原class的所有方法
- 执行Method:Invoke()
3、Constructor
- 获取 :getContructor()
- 构造对象 :newInstance()
4、Field
- 获取 :getFiled()
- 取值 :get()
- 设置值 :set()
5、暴力反射
passwordField.setAccessible(true),获取private等不公开属性时需要暴力反射
五、案例 【框架原理】-springboot为例
shopping: 流程:go—>Buy—>gohome web <–> server
//这个相当于一个配置类,怎么写出来,只要根据写出一个接口
public class Shopping1 {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void go()
{
System.out.println(name+" go to daruifa shopping");
}
public void buy()
{
System.out.println(name+" buy some foods");
}
public void buy(String paper)
{
System.out.println(name+" buy some "+ paper);
}
public void goHome()
{
System.out.println(name + " go home by car");
}
}
1、构造配置参数,并且读取参数
framework.properties
className=com.company.domain.Shopping1
methodGo=go
methodBuy=buy
methodgoHome=goHome
fieldName=name
peopleName=xiaoli
以下为框架核心,不变的部分
Properties properties = new Properties();
ClassLoader classLoader = ShoppingFramework.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("framework.properties");
properties.load(resourceAsStream);
3、设置相关字段
String className = properties.getProperty("className");
String methodGo = properties.getProperty("methodGo");
String methodShopping = properties.getProperty("methodBuy");
String methodgoHome = properties.getProperty("methodgoHome");
String fieldName = properties.getProperty("fieldName");
String peopleName = properties.getProperty("peopleName");
2、构造Class对象
Class aClass = Class.forName(className);
Object shop = aClass.newInstance();
Field peopleField = aClass.getDeclaredField(fieldName);
peopleField.setAccessible(true);
peopleField.set(shop,peopleName);
4、获取方法,调用方法
Method go = aClass.getMethod(methodGo);
go.invoke(shop);
Method shopping = aClass.getMethod(methodShopping);
shopping.invoke(shop);
Method gohome = aClass.getMethod(methodgoHome);
gohome.invoke(shop);