Java反射技术应用广泛,它能够配置:
- 类的全限定名,方法和参数
- 完成对象的初始化
- 反射某些方法
反射内容有:
- 对象构建
- 反射方法
- 注解
- 参数
- 接口
本文主要针对下面两个方面:
- 对象构建(有参数、没参数)
- 方法的反射
在Java中,反射是通过包java.lang.reflect.*来实现的。
反射的优点是只要配置就可以生成对象,可以降低程序的耦合度,比较灵活。
反射的缺点就是运行比较慢。但是大部分情况下为了灵活性,降低程序的耦合度,我们还是会使用反射的,比如SpringIoC容器。
通过反射构建对象
无参数类
在Java中允许通过反射配置信息构建对象,比如下面的ReflectServiceImpl类:
package com.lean.ssm.chapter2.reflect;
/**
* Created by mzg on 2017/12/5.
*/
public class ReflectServiceImpl {
public void sayHello(String name){
System.err.println("Hello"+name);
}
}
通过反射的方法去构建,如下:
//通过反射的方法构建类,无参数
public ReflectServiceImpl getInstance(){
ReflectServiceImpl object = null;
try{
object = (ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl" ).newInstance();
}catch (ClassNotFoundException|InstantiationException|IllegalAccessException ex){
ex.printStackTrace();
}
return object;
}
重点构建语句:
object = (ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl" ).newInstance();
有参数类
有参数类ReflectServiceImpl2:
package com.lean.ssm.chapter2.
/**
* Created by mzg on 2017/12/5.
*/
public class ReflectServiceImpl2 {
private String name;
public ReflectServiceImpl2(String name){
this.name = name;
}
public void sayHello(){
System.err.println("Hello" + name);
}
}
实现一个含参数的构建方法:
//通过反射的方法构建类,有参数
public ReflectServiceImpl2 getInstance(){
ReflectServiceImpl2 object = null;
try {
object = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2").getConstructor(String.class).newInstance("张三");
} catch (InstantiationException|IllegalAccessException|InvocationTargetException|NoSuchMethodException|ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
使用如下代码反射生成对象:
object = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2").getConstructor(String.class).newInstance("张三");
过程:
先通过forName加载到类的加载器。然后通过getConstructor方法,它的参数可以是多个,这里定义为String.class,意为有且只有一个参数类型为String的构建参数。通过这个方法可以对重名方法进行排除,此时再用newInstance方法生成对象,只是newInstance方法多了一个参数“张三”而已。实际就等于 object = new ReflectServiceImpl2("张三),只是这里用反射机制来生成这个对象而已。
反射方法
继续以ReflectServiceImpl类为例,代码如下;
/**
* 类 : ReflectServiceImpl 反射方法
* @return 方法返回值
*/
public Object reflectMethod(){
Object returnObj = null;
ReflectServiceImpl target = new ReflectServiceImpl();
Method method = null;
try {
method = ReflectServiceImpl.class.getMethod("sayHello", String.class);
returnObj = method.invoke(target,"张三");
} catch (NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
e.printStackTrace();
}
return returnObj;
}
对于代码:
method = ReflectServiceImpl.class.getMethod("sayHello", String.class);
当有具体的对象target,而不知道具体是那个类时,也可以使用 target.getClass().getMethod("sayHello",String.class)代替他。
方法 getMethod("sayHello",String.class):
- 第一个参数是方法名称
- 第二个参数是参数类型,是一个列表,多个参数可以继续编写多个类型
方法 returnObj = method.invoke(target,"张三"):
- 第一个参数为target,就是确定那个对象调用方法
- 第二个参数为"张三",等同于 target.sayHello("张三")
- 如果存在多个参数,可以写成Method.invoke(target,obj1,obj2,obj3......)
反射生成对象和反射调度方法的实例,继续以ReflectServiceImpl类为例:
public static Object reflectEx1(){
ReflectServiceImpl object =null;
try {
object = (ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
Method method = object.getClass().getMethod("sayHello", String.class);
method.invoke(object,"张三");
} catch (InstantiationException|IllegalAccessException|ClassNotFoundException|NoSuchMethodException|SecurityException|
IllegalArgumentException|InvocationTargetException e) {
e.printStackTrace();
}
return object;
}
文章评论