zoukankan      html  css  js  c++  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 }

    效果图:

  • 相关阅读:
    SQL server 2005转换为SQL server 2000的方法
    C#异步编程(转)
    在存储过程中如何使用另一个存储过程返回的结果集
    开始研究开源GIS软件之旅(SharpMap和WorldWind)
    WorldWind学习系列一:顺利起航篇
    WorldWind学习系列二:擒贼先擒王篇1
    WebService安全访问(资料收集)
    平台调用:C# 使用非托管dll函数
    VS2008环境下C#对Excel的操作 [C#] (收集转载)
    WorldWind学习系列二:擒贼先擒王篇2
  • 原文地址:https://www.cnblogs.com/zyxsblogs/p/11225233.html
Copyright © 2011-2022 走看看