乐趣区

java反射构建对象和方法的反射调用

java 反射构建对象和方法的反射调用

Java 反射技术应用广泛,其能够配置:类的全限定名,方法和参数,完成对象的初始化,设置是反射某些方法。可以增强 java 的可配置性。

1.1 通过反射构建对象(无参数):

例如我们使用 ReflectServiceImpl 类讲解这个例子

1 public class ReflectServiceImpl {
2 public void sayHello(String name){
3 System.out.println(“hello”+name);
4 }
5 }
我们通过反射的方法去构建它。

复制代码
1 public ReflectServiceImpl getInstance(){
2 ReflectServiceImpl object=null;
3 try {
4 object=(ReflectServiceImpl)Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl”).newInstance();
5 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
6 e.printStackTrace();
7 }
8 return object;
9 }
复制代码
其中第 4 行:object=(ReflectServiceImpl)Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl”).newInstance();

是给类加载器注册一个类 ReflectServiceImpl 的权限定名,之后通过 newInstance 方法初始化一个类对象。

1.2 通过反射构建对象(类的构造器中带有参数):

我们使用 ReflectServiceImpl2 这个类去理解:

复制代码
1 public class ReflectServiceImpl2 {
2 private String name;
3 public ReflectServiceImpl2(String name) {
4 this.name=name;
5 }
6 public void sayHello(String name){
7 System.out.println(“hello”+name);
8 }
9 }
复制代码
此时 ReflectServiceImpl2 的构造器带有参数 public ReflectServiceImpl2(String name){xxxx};

此时我们该如何利用反射生成对象呢?只需要在类加载器注册的使用 getConstructor(参数) 方法。其中参数是我们构造器中的参数的类型。代码如下:

复制代码
1 public ReflectServiceImpl2 getInstance(){
2 ReflectServiceImpl2 object=null;
3 try {
4 object=(ReflectServiceImpl2)Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl2”)
5 .getConstructor(String.class).newInstance(“ 张三 ”);
6 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | InvocationTargetException |NoSuchMethodException e) {
7 e.printStackTrace();
8 }
9 return object;
10 }
复制代码
如 4、5 行所示:

先通过 forName 加载到类的加载器。然后通过 getConstructor 方法,它的参数可以是多个,这里定义 String.class,意为有且只有一个参数类型为 String 的构建方法。通过这个方法可以对重名方法进行排除,此时再用 newInstance 方法生成对象,只是 newInstance 方法也多了一个参数“张三”而已。实际上就等于 object=new ReflectServiceImpl2(“ 张三 ”). 只是利用了反射来生成对象而已。

1.3 反射方法

在使用反射方法之前需要先获取对象,得到了方法才能够去反射。

我们使用 ReflectServiceImpl 类为例。

ReflectServiceImpl 类代码:

1 public class ReflectServiceImpl {
2 public void sayHello(String name){
3 System.out.println(“hello”+name);
4 }
5 }
调用方法:

复制代码
1 public Object reflect(){
2 ReflectServiceImpl object=null;
3 Object returnObj=null;
4 // 反射生成对象
5 try {
6 object = (ReflectServiceImpl) Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl”).newInstance();
7 // 反射生成方法并调度
8 Method method = object.getClass().getMethod(“sayHello”, String.class);
9 returnObj= method.invoke(object, “ 张三 ”);
10 }catch(ClassNotFoundException| NoSuchMethodException| InvocationTargetException| IllegalAccessException| InstantiationException e) {
11 e.printStackTrace();
12 }
13 return returnObj;
14 }
复制代码
当有具体对象 object(类型为 ReflectServiceImpl), 而不知道具体是哪个类的时候,也可以使用 object.getClass().getMethod(“sayHello”, String.class); 来替代它,其中第一个参数是方法的名称,第二个参数是参数类型,是一个列表,多个参数可以继续编写多个类型,这样便能够获得反射的方法对象。反射方法时运用 method.invoke(object, “ 张三 ”); 调用的,第一个参数为 object, 就是确定用哪个对象调用方法,而“张三”是参数,这就等同于 object.sayHello(“ 张三 ”); 若存在多个参数可以写成 Method.invoke(target,obj1,obj2.obj3…),这些要根据对象的具体方法来确定。

1.4 测试

以 ReflectServiceImpl 为例:

复制代码
1 package com.lean.reflect;
2 import java.lang.reflect.InvocationTargetException;
3 import java.lang.reflect.Method;
4 public class ReflectServiceImpl {
5 // 属性
6 private String name;
7 // 默认的构造方法
8 public ReflectServiceImpl() {
9 super();
10 }
11 // 带参数的构造方法
12 public ReflectServiceImpl(String name) {
13 this.name=name;
14 }
15 // 方法 sayHelo
16 public void sayHello(String name){
17 System.out.println(“hello “+name);
18 }
19 // 调用方法
20 public Object reflect(){
21 ReflectServiceImpl object=null;
22 Object returnObj=null;
23 // 反射生成对象
24 try {
25 object = (ReflectServiceImpl) Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl”).newInstance();
26 // 反射生成方法并调度
27 Method method = object.getClass().getMethod(“sayHello”, String.class);
28 returnObj= method.invoke(object, “ 张三 ”);
29 }catch(ClassNotFoundException| NoSuchMethodException| InvocationTargetException| IllegalAccessException| InstantiationException e) {
30 e.printStackTrace();
31 }
32 return returnObj;
33 }
34 // 获取对象
35 public ReflectServiceImpl getInstance(){
36 ReflectServiceImpl object=null;
37 try {
38 object=(ReflectServiceImpl)Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl”).newInstance();
39 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
40 e.printStackTrace();
41 }
42 return object;
43 }
44 // 测试
45 public static void main(String[] args) {
46 ReflectServiceImpl rsl= new ReflectServiceImpl();
47 rsl.reflect();
48 }
49 }

退出移动版