反射 is 框架的灵魂

背景:
我不相信你会问—啥是框架? (简单理解为可复用的代码)像现在很流行的框架如 Spring , Spring boot,Spring AOC 等都是框架,组成它们的代码中总会见到反射机制。

简介:
反射: 将类的组成部分封装成一个对象。
用一张图解释哈:
在这里插入图片描述
过程解释:
还是一个老生常谈的问题,我们用高级语言编写的代码如何被计算机执行? 都知道计算机只能执行机器码。 所以我们编译高级语言代码最终也会生成机器码,只不过中间有一个过度的部分那就是字节码。利用 javac 生成字节码后,我们想执行这个程序。又知道计算机是从内存中读取指令和数据的,我们利用反射将字节码文件加载进内存,然后被计算机所执行。

使用反射的好处:
1 可以在程序运行中操纵这些对象
2 可以解耦,提高程序的可扩展性

===============================================================

应用举例:

获取 Class 对象的方式(可以理解 Class 对象是反射的另一种体现):

1 Class.forName("全类名")    // 将磁盘中的对应代码加载进内存,返回 Class 对象(**多用于配制文件)

2 类名.class    //通过类名的属性获取对象(内存中),(**多用于参数传递)

3 对象.getclass() // getclass()在Object对象中定义着(**多用于对象获取字节码的方式)

//结论

同一个字节码文件(*.class)在一次程序运行中只会被加载一次进内存,不论通过那种方式获取 Class 都是代指同一个对象

Class 对象的功能:


  // 获取内存中的成员变量们
  - cls.getFileds();   // 获取 public 修饰的成员变量
  - cls.getFiled(String name);  // 获取指定 public 修饰的成员变量
  - cls.getDeclaredFileds(); // 获取全部成员变量(忽略修饰符)
  - cls.getDeclaredFiled(String name); // 获取指定成员变量(忽略修饰符)
 注:获取 private 修饰的变量后想给其赋值必须先执行能忽略修饰符的代码--> 
 - cls.setAccessible(True);

 //  获取内存中的构造方法们
   - cls.getConstructor(String.class,int.class);  // 获取指定 public 修饰的构造方法
  - cls.getConstructors(); // 获取 public 修饰的构造方法
   - cls.getDeclaredConstructor(String.class,int.class);// 获取指定 public 修饰的构造方法(忽略修饰符)
  - cls.getDeclaredConstructors();  // // 获取构造方法(忽略修饰符)
  

获取构造方法有啥用呢??? 哈哈,当然是创建对象啦。

   Constructor c =   cls.getConstructor(String.class,int.class);
	Object o =  c.newInstance("ss",70);
	
 // 获取成员方法也是相似的代码(这里就忽略了)

我想看到这里你还是对反射的作用记忆不深刻,也不知道用它来获取对象和获取对应的方法并执行有啥用? 如果你有这个疑问,那么问题就来了:

问: 利用反射机制,写一个框架,可以创建任意对象,执行任意方法。

是不是没有思路??? 是不是觉得虽然知道反射但还是不会用它解决问题?如果你一上来就写代码,根据传入指定的全类名和方法名这种办法,可行是可行但耦合度太高了。
简单的处理是 配制文件+反射(在配置文件内写全类名,和指定要执行的方法名。)

/**
     - 创建配置文件(后缀名一定为 .properties)
     - 创建配置文件对象
     - 获取配置文件
     - 根据配置文件对象获取配置文件内容
     - 根据内容创建对象
      - 根据内容找到方法并执行
 **/
 Properties pro = new Properties();
 //获取配置文件
 InputStream in = getclass.getClassLoad().getResourceAsStream("配置文件路径")
 //加载配置文件
 pro.load(in);
//获取配置文件内的内容
String className = pro.getProperty("className");
String method_name = pro.getProperty("method_name");
//利用反射创建对象,执行对应方法
Class cls = class.forNmae("className");  // 加载对象进内存
Object obj = cls.newInstance(); //创建对象
Method me = cls.getMethod("method_name"); //获取指定方法
me.invoke(obj); //执行指定方法(需要对象为形参)

总结:
上面写到了一些反射的常见用法,以及在框架中如何使用反射机制,极大的简化了代码量。我希望对你有所帮助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章