反射

xiaoxiao2021-02-28  47

java中提供了一种叫做反射的方式,这个东西能够帮助我们架构更加的优美。

之前在项目中,遇到一个问题:对外提供接口,需要根据前端请求的url来进入不同的逻辑执行方法中。如果简单粗暴的通过添加多个if来控制进入不同的方法,就显得不专业了。 新增功能需要添加if判断,完全远离了设计本质。

这篇文章并不是深入其原理,仅在使用层面上花费口舌。(哎,能力有限啊,后续慢慢深入学习)

java为我们提供了一个Class的类(称为类类型),这个类的话可以理解为 管理 开发者所写的所有类。通过Class我们可以通过相应提供的API到 每个开发者所写类(包含jdk的类)的相应Filed属性信息, Method方法信息, Constructor构造函数信息。

相对于开发者所写的类, 都可以找到对应的类类型。如果有类A, A a = new A(); A这个类的类类型可以通过下面三种方式获得 1. a.getClass(); 2. A.class; 3. Class.forName(“A的路径”); 再通过Class的相关API即可进行相应操作

为什么需要反射(例子)?

生活中,大家都会唱歌,有明星唱歌好听的,有孩子唱歌纯真。。。现在我需要根据某个标识来判断 让明星唱歌,还是让孩子唱歌。简单粗暴的方法如下。 简单举一个Child的类,其他类类似

package com.yangs.reflect; /** * Created by Ytadpole on 2018/2/18. */ public class Child{ public void sing() { System.out.println("小孩子的唱歌方式"); } }

主逻辑代码

package com.yangs.reflect; /** * Created by Ytadpole on 2018/2/18. */ public class DynamicAndStaticTest { public static void main(String[] args){ if("child".equals(args[0])){ Child child = new Child(); child.sing(); }else if("start_man".equals(args[0])){ StarMan starMan = new StarMan(); starMan.sing(); } }

非反射弊端简单描述

首先这个程序,需要提前将 StarMan和Child这两个类都建立好,需要加载进入JVM中才能正常执行程序,否则程序编译上就不通过,这个也是传统的通过new方式来创建对象并执行相应的方法。倘若这个时候我需要添加一个MusicTeacher,那有需要在这个逻辑上添加新的if条件。 再说一点,如果 这个主判断 和 新类MusicTeacher是两个人开发,开发主判断的人 需要等待 开发MusicTeacher这个类完成。在MusicTeacher这个功能完成之前, 主逻辑都不能添加与其相关的代码。

那怎么解决?接下来就到 反射 和接口了。

反射

首先看主逻辑

package com.yangs.reflect; /** * Created by Ytadpole on 2018/2/18. */ public class DynamicAndStaticTest { public static void main(String[] args){ try { Class clazz = Class.forName("com.yangs.reflect.Child"); Child child = (Child) clazz.newInstance(); child .sing(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }

先获取到对应的类类型Class,通过Class的API newInstance()得到对应的实例。这里返回处 有可能实例是Child的实例,也有可能是StarMan的实例,以及后续我们会新增更多的实例。还是要根据不同的情况,强制转化为不同的类实例,那这样就有问题。 这个时候我们就通过让我这些StarMan,Child实现于同一个**接口**SingAble,这就体现到接口的作用了。

接口配合反射

package com.yangs.reflect; /** * Created by Ytadpole on 2018/2/18. */ public interface SingAble { void sing(); }

对应其他的Child类实现SingAble接口

package com.yangs.reflect; /** * Created by Ytadpole on 2018/2/18. */ public class Child implements SingAble{ @Override public void sing() { System.out.println("小孩子的唱歌方式"); } }

这时主逻辑对应修改

package com.yangs.reflect; /** * Created by Ytadpole on 2018/2/18. */ public class DynamicAndStaticTest { public static void main(String[] args){ try { Class clazz = Class.forName("com.yangs.reflect.Child"); SingAble singAble = (SingAble) clazz.newInstance(); singAble.sing(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }

再次简单描述

这样,通过反射,我们只需要用到哪个类就去加载哪个类,后续有新的MusicTeacher,也无需修改主逻辑代码,体现出设计的艺术。 同时,新增的MysicTeacher这些功能实现SingAble接口,也体现到接口的作用。各部分开发互补影响。

Class对应API还有其他许多功能自行查阅摸索。

转载请注明原文地址: https://www.6miu.com/read-2622729.html

最新回复(0)