设计模式——反射

本文说明:在学习《Java EE互联网轻量级框架整合开发》此书时,里面提到了几种设计模式,我在学习这几种设计模式时写了笔记,放上来让大家共同学习,如果有错误,望指出。

本章由两部分组成:

1、基本概念+关键代码讲解

2、完整例子

基本概念+关键代码讲解

反射就是不通过new却能得到对象的一种方法,主要的用途是通过配置文件等字符串信息能够动态构造对象,可以通过配置配置文件灵活修改对象实例,而不需要通过修改代码。

根据构造器的不同,有下列两种语法(方便说明省略了异常捕获,下同):

//空构造器的
ReflectTarget target = (ReflectTarget) Class.forName("com.amiao.ReflectTarget")
                            .newInstance();

//带参构造器的
ReflectTarget target = (ReflectTarget)Class.forName("com.amiao.ReflectTarget")
                            .getConstructor(String.class).newInstance("Amiao");

那么通过上述两个之一的代码,即可得到目标对象。可以封装到一个getInstance()方法里面,通过返回值即可传回目标对象,进而通过对象想要调用什么方法则随便调用。

接下来我们看看反射方法,与直接通过对象+“.”调用的不同,反射能够调用到private方法。

反射方法同样有两种实现方式,一种是通过“类名.class.getMethod()”去直接获得,一种是通过对象“target.getClass().getMethod()”获得Method对象,进而通过它能够实现原方法调用及得到返回值,代码如下:

//通过类名获得
Method method = ReflectTarget.class.getMethod("method1", String.class);//getMethod()里面有两个参数,一个是被反射的方法名,一个是该方法的参数类型

//通过对象获得
ReflectTarget reflectTarget = new ReflectTarget();    //这里也可以用上述反射得到对象。
Method method = reflectTarget.getMethod("method1", String.class);

得到Method对象后,如何使用?采用下列语法:

Object returnObj = method.invoke(reflectTarget, "Hello world");

这里相当于Object returnObj = reflectTarget.method1("Hello world");

再把它封装到一个方法里,放回returnObj,就跟原来的method1一样了,随时可以被调用。

完整例子

//包括三个类:target类,使用类,测试类

//target类
package com.amiao.design_pattern.reflect;
class ReflectServiceImpl {
    private String helloName;

    //不写则jdk默认加上空构造方法,但它会被有参数的构造方法覆盖,如果两个都想使用,则需写。
    public ReflectServiceImpl() {}

    public ReflectServiceImpl(String helloName) {
        this.helloName = helloName;
    }

    public void sayHello() {
        System.out.println("Hello " + (helloName == null ? "空" : helloName));
    }

    public String testReflectMethod() {
        System.out.println("Reflect Success");
        return "Return Object Success";
    }
}

//使用反射的类
package com.amiao.design_pattern.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectUse {
    //new install without constructor
    public ReflectServiceImpl getInstance() {
        try {
            ReflectServiceImpl rsi = (ReflectServiceImpl) Class.forName("com.amiao.design_pattern.reflect.ReflectServiceImpl").newInstance();
            return rsi;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {    //如果构造方法为private会抛此异常
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }

    //new install with constructor
    public ReflectServiceImpl getInstance1() {
        try {
            ReflectServiceImpl rsi = (ReflectServiceImpl) Class.forName("com.amiao.design_pattern.reflect.ReflectServiceImpl").getConstructor(String.class).newInstance("Amiao");
            return rsi;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    //invoke method with class's name
    public Object reflectMethod() {
        Object returnObj = null;
        ReflectServiceImpl target = new ReflectServiceImpl();
        try {
            Method method = ReflectServiceImpl.class.getMethod("testReflectMethod");
            returnObj = method.invoke(target);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return returnObj;
    }

    //invoke method with reflect object's class's name
    public Object reflectMethod1() {
        Object returnObj = null;
        try {
            ReflectServiceImpl target = (ReflectServiceImpl) Class.forName("com.amiao.design_pattern.reflect.ReflectServiceImpl").newInstance();
            Method method = target.getClass().getMethod("testReflectMethod");
            returnObj = method.invoke(target);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return returnObj;
    }
}

//测试代码
package com.amiao.design_pattern.reflect;
public class TestMain {
    public static void main(String args[]) {
        ReflectUse ru = new ReflectUse();
        ReflectServiceImpl rsi = ru.getInstance();
        rsi.sayHello();
        rsi = ru.getInstance1();
        rsi.sayHello();
        System.out.println(ru.reflectMethod());
        System.out.println(ru.reflectMethod1());
    }
}

/*
* 运行结果
* Hello 空
* Hello Amiao
* Reflect Success
* Return Object Success
* Reflect Success
* Return Object Success
* */

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值