Java核心API之反射

一、什么是Java反射

    Java反射是Java语言自身提供的一种运行机制,主要作用是实现类的动态加载,增加程序的灵活性,实现程序的进一步解耦,举个例子
class  Office
{
    public static void main(String[] args) 
    {
        //new 创建对象是静态加载类,在编译时刻就需要加载所有可能使用到的类
        //通过动态加载类可以解决该问题
        if("Word".equals(args[0]))
        {
            Word w = new Word();
            w.start();
        }
        if("Excel".equals(args[0])){
            Excel e = new Excel();
            e.start();
        }
    }
}

运行结果:
这里写图片描述
出现这类错误的是因为通过new关键字创建的对象是静态加载的,意思就是在编译阶段就会被创建,可是现在还不存在Word类和Excel类,所以无法通过编译
解决方法是变动态加载为静态加载,即使用Java反射机制,具体实现如下:
先说一句帮助大家理解的话:在Java中万事万物皆对象,那么我们自己写的类也是对象,是Java中Class类的对象

class  Office
{
    public static void main(String[] args) 
    {

        if("Word".equals(args[0]))
        {
            try{
            //调用Class类的forName方法,根据类名获取反射
            Class c1 = Class.forName("Word");
            //调用Class类的newInstance方法创建对象
            Word w =(Word) c1.newInstance();
            }catch(Exception e){
            e.printStackTrace();
            }
            //Word w = new Word();
            //w.start();
        }
        if("Excel".equals(args[0])){
            //Excel e = new Excel();
            //e.start();
        }
    }
}

运行结果:
这里写图片描述
这样程序编译的时候就不会报错了,因为现在的对象是在运行阶段创建的,只有当你用到某个类的实例对象时该对象才会被创建。
那么如何实现程序的的进一步解耦呢,同样举例说明:
首先,我们需要创建一个接口类来制定一个人统一的标准

interface OfficeAble
{
    public void start();
}

然后让Word类和Excel类来实现这个接口
Word类:

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

Excel类:

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

然后是修改后的Office类:

class  OfficeBetter
{
    public static void main(String[] args) 
    {
        try{
            //根据传入的参数创建该参数的反射(官网称为类类型)
            Class c1 = Class.forName(args[0]);

            //上转型,创建传入参数类的实例对象
            OfficeAble oa =(OfficeAble)c1.newInstance();
            oa.start();
        }
        catch(Exception e)
            {
            e.printStackTrace();
        }
    }
}

运行结果:
这里写图片描述
通过将类型参数化就实现了等号右边的解耦,可以根据需要调用的类的不同创建不同类的实例化对象,这样以后不管你其他的类怎么改动都不需要再改动此处代码。

猜你喜欢

转载自blog.csdn.net/star_in_shy/article/details/77759203
今日推荐