Java反射学习
Java的反射技术应用广泛,它能够配置:类的权限定名、方法和参数,完成对象的初始化,甚至是反射某些方法。这样就可以大大增强Java的可配置性,Spring IoC的基本原理也是如此,当然Spring IoC的代码要复杂的多。
Java的发射内容繁多,包括对象的构造、反射方法、注释、参数、接口等。本人最近学习了对象构建和方法的反射调用,主要从这两方面来撰写该文章。在Java中,反射是通过包java.lang.reflect.*实现的。
一、通过反射构建对象
(一)无参构造对象
在Java中允许通过反射配置信息和构建对象,代码如下所示:
public void sayHello(String name) {
System.out.println("Hello Reflect " + name);
}
然后通过反射的方法构造它,代码如下所示:
public ReflectServiceImpl getInstance() {
ReflectServiceImpl reflectServiceImpl = null;
try {
reflectServiceImpl = (ReflectServiceImpl)Class.forName("com.chenbin.reflect.ReflectServiceImpl")
.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return reflectServiceImpl;
}
这里的代码就是生成一个对象,然后将其返回。下面这段代码的目的就是给类加载器注册了一个类ReflectServiceImpl的全限定名,然后通过newInstance方法初始化了一个类对象,使用反射的方式也是什么简单。
reflectServiceImpl = (ReflectServiceImpl)Class.forName("com.chenbin.reflect.ReflectServiceImpl")
.newInstance();
(二)有参构造对象
以上是没有任何参数的类的反射生成,如果一个类的所有构造方法里都至少存在一个参数,如何用反射构造它。在Java中,只要稍微改变一下就可以了,代码如下所示:
public class ReflectServiceImpl2 {
private String name;
public ReflectServiceImpl2(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("Hello " + name);
}
}
这里实现了含有一个参数的构造方法,这时将不能用之前的办法将其反射生成对象,用一下代码可以完成相同的功能,代码如下所示:
public ReflectServiceImpl2 getInstance() {
ReflectServiceImpl2 reflectServiceImpl2 = null;
try {
reflectServiceImpl2 = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2")
.getConstructor(String.class).newInstance("张三");
} catch (Exception e) {
e.printStackTrace();
}
return reflectServiceImpl2;
}
使用如下代码反射生成对象:
reflectServiceImpl2 = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2")
.getConstructor(String.class).newInstance("张三");
先通过forName加载到类的加载器。然后通过getConstructor方法,它的参数可以是多个、还可以是实体对象,这里定义为String.class,意为有且只有一个参数类型为String的构建方法。通过这个方法可以对重名方法进行排除,此时再用newInstance方法生成对象,只是newInstance方法也多一个参数"张三"而已。实际等于reflectServiceImpl2 = new ReflectServiceImpl2("张三"),只是这里用反射机制来生成这个对象而已。
反射的优点是只要配置就可以生成对象,可以解除程序的耦合度,比较灵活。反射的缺点是运行比较慢。但是大部分情况下为了灵活,降低程序的耦合度,我们还是会使用反射的,比如Spring IoC容器。
二、反射方法
以下主要介绍反射方法,在使用反射方法前要获取方法对象,得到了放大才能够反射,代码如下所示:
public Object reflectMethod() {
Object returnObj = null;
ReflectServiceImpl reflectServiceImpl = new ReflectServiceImpl();
try {
Method method = ReflectServiceImpl.class.getMethod("sayHello", String.class);
returnObj = method.invoke(reflectServiceImpl,"张三");
} catch (Exception e) {
e.printStackTrace();
}
return returnObj;
}
我们来看这段代码Method method = ReflectServiceImpl.class.getMethod("sayHello", String.class);当有具体的对象target,而不知道具体是哪个类时,也可以使用target.getClass.getMethod("sayHello"。String.class)代替它,其中第一个参数是方法名称,第二个参数是参数类型,是一个列表,多个参数可以继续编写多个类型,这样便能获得反射的方法对象。反射方法是运用returnObj = method.invoke(target,"张三");代码完成的,第一个参数为target,就是确定用哪个对象调用方法,而"张三"是参数,这行就等同于target.sayHello("张三");。如果存在多个参数,可以写成Method.invoke(target,obj1,obj2,obj3...),这些要根据对象的具体方法来确定。
实例:
通过实例来看看如何反射生成对象和反射调度方法,代码如下所示:
public Object reflect() {
ReflectServiceImpl object = null;
try {
object = (ReflectServiceImpl)Class.forName("com.chenbin.reflect.ReflectServiceImpl")
.newInstance();
Method method = object.getClass().getMethod("sayHello", String.class);
method.invoke(object,"张三");
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
以上就是对反射的学习,希望对看到的大家有所帮助,后续会学习Java设计模式,文章会持续更新哦,记得关注哟!