JAVA中的反射机制以及在Spring中的应用

2023-11-15

一 反射机制

反射机制,就是指程序可以获得自己的属性和方法。java中,只要知道类的名字,就可以通过反射机制获取类的所有属性以及方法

二 反射机制的使用-Class类

java中的反射机制,主要靠Class类实现,java.lang.Class是一个特殊的类,用于封装jvm中加载的类对象的信息,每个类加载后都会对应生成一个Class对象,可以通过类名获取该对象的属性、方法,甚至创建该对象

三 为什么要使用反射

如果想要获得对象信息,或者对象方法,亦或是创建对象,那我们直接new对象不就好了,干嘛要使用反射机制呢?这涉及到静态编译和动态编译的问题,我们都知道,java是一种先编译后运行的语言,区别就在编译方式上:

3.1 静态编译

编译时绑定对象,确定类型,程序在运行时直接加载对象,不必再编译

3.2 动态编译

运行时确定类型,绑定对象,程序运行时用到该对象才会编译再加载,更加灵活

3.3 反射的好处

反射使用的方式就是动态编译,在运行时创建对象,运行时访问对象属性和方法,他有以下几个好处

  • 程序运行时动态创建对象,访问方法,灵活而且解耦
  • 在大型程序中我们很难直接完善所有功能,这种方式支持我们动态地完善程序,寻常的静态编译方法必须将程序卸载或者重新编译才能获得扩展,所以这种方法也符合开闭原则

3.4 反射的缺点

由于运行时比静态编译多了一次编译过程,所以运行效率必然会不如静态编译直接使用对象的功能或方法,但是最近版本中,这个速度差别已经被降低到1-2倍

四 Spring IOC中的体现

4.1 Spring IOC的实现方式

Spring IOC就是靠工厂模式+反射实现的,体现了五大设计原则中的依赖倒置原则,开闭原则,里式替换原则,如果对这几个原则不太熟悉的,可以看一下我的另一篇博客:java面向对象五大原则.结合这几个原则就可以发现Spring IOC的优美之处

4.2 代码实现纯工厂模式

//首先定义一个接口类
public interface human {
    public void eat();
}
// 然后实现男女类继承该接口类

public class man implements human{

    @Override
    public void eat() {
        System.out.println("男人的吃法");
    }
}
public class woman implements human{
    @Override
    public void eat() {
        System.out.println("女人的吃法");
    }
}
//最后实现工厂类
public class humanFactory {
    public human getInstance(String objectname){
        if(objectname.equals("man")){
            return new man();

        }else if(objectname.equals("woman")){
            return new woman();

        }else{
            return null;
        }
    }
}

这里可以看见,我们使用工厂管理对象的创建,但是有一个问题,每次要增加类的话都要去修改工厂,岂不是很麻烦,因此我们使用反射的方法重新实现一下

4.3 反射+工厂模式

//首先定义一个接口类
public interface human {
    public void eat();
}
// 然后实现男女类继承该接口类

public class man implements human{

    @Override
    public void eat() {
        System.out.println("男人的吃法");
    }
}
public class woman implements human{
    @Override
    public void eat() {
        System.out.println("女人的吃法");
    }
}
//最后实现工厂类
public class humanFactoryReflect {
    public human getInstance(String objectname) {
        human human = null;
        try {
            human = (human) Class.forName(objectname).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return human;

    }
}

可以看到,我们使用反射机制后,如果需要扩展human的种类,就不再需要修改工厂模式,而是只需要继续增加需要的类实现接口,只需要知道类的权限定名就可以通过工厂创建对象,优美地满足了开闭原则

4.4 配置文件+反射+工厂模式=Spring IOC

首先创建一个human的配置文件,human.porperties

man=com.springIOC.man
woman=com.springIOC.woman
//首先定义一个接口类
public interface human {
    public void eat();
}
// 然后实现男女类继承该接口类

public class man implements human{

    @Override
    public void eat() {
        System.out.println("男人的吃法");
    }
}
public class woman implements human{
    @Override
    public void eat() {
        System.out.println("女人的吃法");
    }
}
//操作属性文件类
class init{
    public static Properties getPro() throws FileNotFoundException, IOException{
        Properties pro=new Properties();
        File f=new File("human.properties");
        if(f.exists()){
            pro.load(new FileInputStream(f));
        }else{
            pro.setProperty("man", "com.springIOC.man");
            pro.setProperty("woman", "com.springIOC.man");
            pro.store(new FileOutputStream(f), "FRUIT CLASS");
        }
        return pro;
    }
}
//最后实现工厂类
public class humanFactoryReflect {
    public human getInstance(String objectname) {
        human human = null;
        try {
            human = (human) Class.forName(objectname).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return human;

    }
}

有了配置文件后,我们可以通过配置文件的属性,避免写权限定名的麻烦,spring ioc就是使用了这种方式

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA中的反射机制以及在Spring中的应用 的相关文章

随机推荐