反射

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();
        }
    }

非反射弊端简单描述

首先这个程序,需要提前将 StarManChild这两个类都建立好,需要加载进入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还有其他许多功能自行查阅摸索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ytadpole

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值