本文说明:在学习《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
* */