Java 静态加载类与动态加载类(初步认识Java的反射)


最近在做项目用到spring 框架,好多功能只会用,却不知道其中的原理。如果让我写一个框架,我只会for循环、接口、类等一些教科书上前几章节的知识点。

毕竟从接触Java,做java项目到现在已经有一年,用的都是C#和Java通用的部分(以前读书的时候用C#写过毕业设计而已,都是皮毛,至少我是这样觉得的。)

为了能更好理解框架的实现原理,了解到Java有种机制叫“反射”,动态加载类、泛类型等都用到反射这个吊炸天的机制。


一,反射的初步认识

类的反射, 先看一段代码:

public static void main(String[] args) {
        Foo foo = new Foo();        ///<
	Class c1 = Foo.class;       ///<获取Foo类的类类型
	Class c2 = foo.getClass();  ///<获取foo对象的类类型 
	Class c3 =null;
	try {
		c3 = Class.forName("util.reflect.Foo");///<需要写完整的包名和类名
                Foo foo2 = c3.newInstance();   ///< 创建Foo的对象
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
        System.out.println(c1 == c2);
	System.out.println(c2 == c3);
}

class Foo{
	void print(){
		System.out.println("我是Foo类的方法");
	}
}


输出是:

true

true

        

为什么,明明c1和c2是不同对象(我一开始也是搞不明白)。

        原来,在Java中,万事万物皆对象,除了我们new出来的对象,还有我们定义的类(其实它是Class的对象,类的类类型)。

        所以c1, c2, c3 全部都是同一个类类型Foo,它们是Class的一个“唯一对象”(这么称呼是不对的,只是好理解)。 官方给出的解释:“c1和c2表示Foo类的类类型”

以上,就是对类的放射的初步认识。它们怎么用呢?


         二,动态加载类和静态加载类


先来看看,一年前我写的代码(不忍直视啊。。。),有三个文件:Office.java, Excel.java, Word.java

Office.java

class Office{
    public static void main(String[] args){
        if("Word".equals(args[0])){
            Word w = new Word();
            w.start();
        }
        
        if("Excel".equals(args[0])){
            Excel e = new Excel();
            e.start();
        }
    }
}


Word.java

class Word{
    public void start(){
        System.out.println("word start...");
    }
}


Excel.java

class Excel{
    public void start(){
        System.out.println("excel start...");
    }
}


           从编译到运行,没什么问题。仔细一想,就有好多潜在的问题:

  1) 对于Office.java 而已,如果我只用Word类,是必须要把Word类和Excel类都定义出来,不然编译都不通过;

  2)后续拓展,如果我要加一个PPT类,除了手动添加一个PPT类,我还得改原来得Office代码,而且是复制粘贴一小段代码;

  3)静态加载的坏处等等。。


            经过K书,看视频,查别人写得博客,我把代码改进了一下,有四个文件:OfficeBetter.java,  Excel.java, Word.java, OfficeAble.java,


OfficeBetter.java

class OfficeBetter{
    public static void main(String[] args){
        try{
            Class c = Class.forName(args[0]);                  ///<获取第一参数的类类型
            //System.out.println(args[0]);
            OfficeAble oa = (OfficeAble) c.newInstance();      ///<新建一个对象
            oa.start();                 
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}


OfficeAble.java

interface OfficeAble{

    ///< 指定一套标准
    public void start();
}


Word.java

class Word implements OfficeAble{
    public void start(){
        System.out.println("word start...");
    }
}


Excel.java

class Excel implements OfficeAble{
    public void start(){
        System.out.println("excel start...");
    }
}





         这样子写了之后,有几点好处:

   1) 就算没有word类和Excel类,OfficeBetter类依旧可以编译通过;

   2) 如果添加一个PPT类,只需增加一个PPT类并实现OfficeAble这个接口即可,不用修改OfficeBetter类;

   3)动态加载的好处等等。。





  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值