java中的反射实例--看不懂我多吃两碗饭给你看

这里并不对Class类对象中的方法进行过多描述,直接以案例来讲一下反射的作用,如果想了解反射可以先看这篇https://blog.csdn.net/weixin_43400205/article/details/99759760
顺带给观众老爷们附上反射API一份:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

例:

比如说我们现在有一个项目是举办一个晚会:晚会的流程是开始—节目表演----结束
我们先创建一个Party类

public class Party {
    public static void main(String[] args) {
    
        System.out.println("晚会开始");
        
        System.out.println("cxk唱歌:鸡你太美");    
        
        System.out.println("Hjx跳舞:Popping");

        System.out.println("晚会结束");
    }
}

既然我们用的是java,肯定不能这样写,要用面向对象的思维去写代码,代码都放到主业务类里面肯定是不行的,这种紧耦合会造成代码的拓展性和维护性很差,那么我们把节目封装成对象,通过new对象的形式来达到效果

public class Cxk{
 	//  Cxk类,有sing的方法
    public void sing() {
        System.out.println("cxk唱歌:鸡你太美");
    }
}

public class Hjx {
    //Hjx类,有跳舞的方法    
    public void dance() {
        System.out.println("Hjx跳舞:Popping");
    }
}

那么现在我们主业务类的代码应该是

public class Party {

    public static void main(String[] args){
    
        System.out.println("晚会开始");

        Cxk cxk = new Cxk();
        cxk.sing();

        Hjx hjx = new Hjx();
        hjx.dance();

        System.out.println("晚会结束");
    }
}

按理说我们应该这样写,但是问题来了,客户要修改需求,不要Cxk来了,换成电鳗来,那么我们要创建一个电鳗类,new他的对象,调用他的方法

public class Wyf{

    public void sing() {
        
        System.out.println("Wyf电音:大碗面宽");

    }
}

此时的主业务类变成了

public class Party {

    public static void main(String[] args){


        System.out.println("晚会开始");
        
        //Cxk cxk = new Cxk();
        //cxk.sing();
        
        Wyf wyf = new Wyf();
        wyf.sing();

        Hjx hjx = new Hjx();
        hjx.dance();

        System.out.println("晚会结束");
    }
}

需求是解决了,但是问题又来了,如果需求再次更改,那么我还要再写那么多,用什么可以减少代码修改量呢,这时候我们发现,cxk和电鳗都是歌手,有共同的方法唱歌,我们可以把他们共有的方法抽出来,我们使用多态的方式来减少代码修改量,创建一个接口Singer定义一个方法sing

public interface Singer {
    public void sing();
}

Cxk和Wyf分别实现这个接口,重写sing方法

public class Cxk implements Singer{
    @Override
    public void sing() {
        System.out.println("cxk唱歌:鸡你太美");
    }
}
public class Wyf implements Singer {
    @Override
    public void sing() {
        System.out.println("Wyf电音:打完面宽");
    }
}


这是我们的主业务类就是

public class Party {

    public static void main(String[] args){


        System.out.println("晚会开始");
		//如果我们需要变更选手,只需要把Cxk变成Wyf就行
        Singer singer = new Cxk();
        singer.sing();
        
        Hjx hjx = new Hjx();
        hjx.dance();

        System.out.println("晚会结束");
    }
}

通过使用多态,我们变更需求需要修改两行代码,现在只需要修改一下new的实现类,但是改多改少终归是改了主业务类,我们能否在不修改主业务类的情况下实现需求变更?这时我们可以使用工厂模式,创建一个晚会工厂

public class PartFactory {
	//因为不需要实例化,我们将getSinger定义成静态的
	//通过getSinger方法返回一个歌手对象
	//当然我们还可以写dancer对象,都是一样的,就不写了
    public static Singer getSinger(){
        Singer singer = new Cxk();
        return singer;
    }
}

主业务类的代码现在就是

    public static void main(String[] args){


        System.out.println("晚会开始");

        Singer singer = PartFactory.getSinger();
        singer.sing();

        Hjx hjx = new Hjx();
        hjx.dance();

        System.out.println("晚会结束");
    }
}

如果我们要更换选手,只需要将工厂中的new Cxk()换成new Wyf(),主业务类中代码不用更改,但是现在还有个问题,更改代码,就意味着要重新编译,重新编译就要重新启动,就意味着要停服更新,相信每一个玩家都体会过停服更新的痛苦,那么我们如何做到不用重启服务器就实现需求的变更呢?现在引入主角:反射,我们将工厂类的代码改一改

public class PartFactory {

    public static Singer getSinger() throws Exception {
   	    //通过Class.forName(完全限定名)的方式来获取该类的Class对象
        Class<?> clazz = Class.forName("com.xy.party.Cxk");
        //使用类对象中的newInstance方法创建该类的实例对象
        //强转一下,抛出异常
        Singer singer = (Singer) clazz.newInstance();
        return singer;
    }
}

现在我们修改的话,只需要修改字符串就行了,虽然还没有达到效果,但是从修改代码变成了修改字符串,字符串我们可以放到文件中,我们把字符串放到一个properties文件中,读取文件就行了,代码需要编译,文件不需要编译,不需要编译就意味着不用重启服务器,就不用管停机更新,可以不停机更新
首先创建一个properties文件,写上键和值

singer=com.xy.party.Wyf

同时工厂中的代码变成了

public class PartFactory {

    public static Singer getSinger() throws Exception {
        InputStream in = PartFactory.class.getResourceAsStream("/party.properties");
        Properties pro = new Properties();
        pro.load(in);
        String className = pro.getProperty("singer");
        Class<?> clazz = Class.forName(className);
        Singer singer = (Singer) clazz.newInstance();
        return singer;
    }
}

主业务类中的代码还是

public class Party {

    public static void main(String[] args) throws Exception {


        System.out.println("晚会开始");

        Singer singer = PartFactory.getSinger();
        singer.sing();

        Hjx hjx = new Hjx();
        hjx.dance();

        System.out.println("晚会结束");
    }
}

这时候我们修改需求,只需要修改properties配置文件中的内容就可以,不需要修改代码,不需要重新编译,就像写web项目,无论我们修改静态代码还是动态代码,都需要重新部署一下,但是如果我们修改的是数据库里面的数据,那么只要刷新一下页面就行了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值