zoukankan      html  css  js  c++  java
  • Java的反射

    反射的定义:指程序运行期间,能够观察类的属性和方法、以及修改类的对象的属性和行为的特征。

    也可以理解为:动态的获取和修改类的机制。

      反射区别与new,new是静态获取类,而反射是动态。在性能上,动态差于静态。因为new是可以直接确定new哪一个对象,而

        反射确定哪一类的对象需要一个反射验证的过程。

      静态:把类都编写好,编译通过,进行运行。

      动态:类都编写好,也能运行,在运行期间动态获取类的信息、修改类的属性。

    反射最大的应用是框架,spring中一切都是反射,struts、Hibernate都是通过类的反射开发的。

    最常见的应用场景:

      1.使用jdbc链接数据库

      2.servlet在web容器中的加载和运行。

    当然这些理解比较抽象,下面列举一个示例,便于理解。

    一个项目在运行中,需要对一些优惠方案进行调整,但是项目不能停止运行,需要在ABC三个优惠方案中选择。

    /**
    * 公共优惠方案父类
    */
    public class YouhuiFather {
    public void test(){
    System.out.println("我是公共的优惠方案父类!");
    }
    }

    /**
    * 优惠方案A
    */
    public class YouhuiA extends YouhuiFather{
    public void test(){
    System.out.println("我是公共的优惠方案A");
    }
    }

    /**
    * 优惠方案B
    */
    public class YouhuiB extends YouhuiFather{
    public void test(){
    System.out.println("我是公共的优惠方案B");
    }
    }

    /**
    * 优惠方案C
    */
    public class YouhuiC extends YouhuiFather{
    public void test(){
    System.out.println("我是公共的优惠方案C");
    }
    }

    fanan.properties 是优惠方案配置文件,用于调整选择ABC方案
    fangan=model.YouhuiB

    /**
    * 读取优惠方案的类
    */
    public class Factory {
    private String fangan;//配置文件key
    /**
    * 获取选择优惠方案
    */
    public Object chooseYouhui() throws Exception{
    Properties properties=new Properties();
    String fileName="fanan.properties";
    //以流的方式读取配置文件
    InputStream stream=Factory.class.getClassLoader().getResourceAsStream(fileName);
    properties.load(stream);
    fangan=properties.getProperty("fangan");//读取配置文件方案
    //动态拿到优惠方案的实例,修改配置文件不需要项目重启
    Object object=Class.forName(fangan).newInstance();
    return object;
    }
    }

    /**
    * 调用优惠方案类
    */
    public class Client {

    private YouhuiFather youhui;//调用的方案

    public Client(YouhuiFather youhui) {
    this.youhui = youhui;
    }
    /**
    * 调用优惠方案
    */
    public void diaoyong(){
    youhui.test();
    }
    /*传统方式利用new对象的方式来解决,用选择结构进行判断
    如果是A方案就new一个A方案的对象,并调用A的优惠方案,以此类推
    可以看出将是一大串的代码
    特点是方便修改,只需要修改配置文件,方便运维人员修改*/
    }

    /**
    * 测试类
    */
    public class TestYouhui {
    public static void main(String[] args) throws Exception {
    Factory factory = new Factory();
    try {
    YouhuiFather youhui = (YouhuiFather) factory.chooseYouhui();
    Client client = new Client(youhui);
    client.diaoyong();//调用优惠
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    这样,运维人员只需要修改配置文件就可以达到切换优惠方案的效果。而不需要像new对象那样写死?是不是跟jdbc链接池的配置很像呢?

    那么上述代码反射的模式是否可以用new取代呢?当然是可以的,你可以发现核心类Factory获取配置文件

    属性后,完全可以加一个选择结构来选择优惠方案,比如读取“youhuiC”,那么就new一个YouhuiC的对象返回。

    一样是可以实现功能的。缺点有两点:

      1.代码相比上面要臃肿很多。

      2.不方便修改,如果增加一个D、F优惠方案呢?则逻辑代码也需要添加判断。当然你也可以反驳说这个在选择结构上

      做文章,同样能被取代,因为我也想到了。好吧,代码的世界就是这么神奇,无穷无尽,但是反射的确够简单。

    
    


  • 相关阅读:
    轮播插件unsilder 源码解析(二)
    轮播插件unsilder 源码解析(一)---源码解析
    轮播插件unsilder 源码解析(一)---使用
    jquery插件扩展的学习
    基于canvas的陈列订货的分析
    grunt安装和使用教程
    2016订货会项目总结2
    2016工作项目完成总结
    不使用递归法求值
    easy bootstrap模板
  • 原文地址:https://www.cnblogs.com/zeussbook/p/9281878.html
Copyright © 2011-2022 走看看