Java通过反射创建对象

  • 通过反射创建对象

    创建对象之前,我们必须先知道要为哪个类创建对象。我们需要拿到这个类的全路径名。类似java.lang.String,除此之外我们还需要知道这个类的构造函数,是否有参数,参数的类型各是什么。下面分两种情况

    1. 无参构造函数

      Class clazz = null;
      try{
          //这里forName方法可能会抛出找不到类的异常
          clazz = Class.forName("java.lang.String");
      }catch (ClassNotFoundException e1){
          e1.printStackTrace();
      }
      
      String str;
      try{
          //这是最简单的一种实例化方法
          str = (String)clazz.newInstance();
          System.out.println(str.isEmpty());
      }catch (InstantiationException e1){
          // TODO Auto-generated catch block
          e1.printStackTrace();
      }catch (IllegalAccessException e1){
          // TODO Auto-generated catch block
          e1.printStackTrace();
      }
      

      直接调用class对象的newInstance方法,这可以应对大部分情况。

    2. 有参构造函数

      首先我们写一个测试需要用到的类,包含了3个参数不同的构造函数。

      package test11;    
      
      public class ThisIsTestClass{
      
          public ThisIsTestClass(){
              System.out.println("无参构造器");
          }
          public ThisIsTestClass(String str){
              System.out.println("一参构造器,参数为:" + str);
          }
          public ThisIsTestClass(String str, Integer i){
              System.out.println("二参构造器, 参数为:" + str + ", " + i);
          }
      }

      接下来我们用下面的代码来演示,如何调用参数不同的构造函数。

          try{
      
              Class clazz = Class.forName("test11.ThisIsTestClass");
              /**
               *调用无参构造函数,
               * 效果上和使用class.newInstance()差不多
               * 构造函数无参的情况下,可以传入一个空数组,也可以不传入数组
               **/
              Constructor<ThisIsTestClass> con = clazz.getConstructor();
              ThisIsTestClass thisIsTestClass = con.newInstance();
              System.out.println("-------------------------------------");
              //依然是无参构造函数
              Class[] paramTypeEmpty = {};
              Constructor<ThisIsTestClass> con0 = clazz.getConstructor(paramTypeEmpty);
              Object[] paramEmpty = {};
              ThisIsTestClass thisIsTestClassEmpty = con0.newInstance(paramEmpty);
              System.out.println("-------------------------------------");
      
              //getConstructor接受变长参数,以Class数组形式传入,
              //告诉jdk我们要调用哪个构造器
              Class[] paramType1 = {String.class};
              Constructor<ThisIsTestClass> con1 = clazz.getConstructor(paramType1);
      
              //Constructor实例的newInstance同样也是接受一个变长参数,
              //参数数组中类型要和getConstructor的类型对应
              Object[] params1 = {"ParamOne"};
              ThisIsTestClass thisIsTestClass1 = con1.newInstance(params1);
              System.out.println("-------------------------------------");
      
              //params2中的数据类型要和paramTypes2中的类型相对应
              Class[] paramTypes2 = {String.class, Integer.class};
              Constructor<ThisIsTestClass> con2 = clazz.getConstructor(paramTypes2);
              Object[] params2 = {"ParamOne", 2};
              ThisIsTestClass thisIsTestClass2 = con2.newInstance(params2);
              System.out.println("-------------------------------------");
          }catch(ClassNotFoundException e){
              e.printStackTrace();
          }catch (NoSuchMethodException e){
              e.printStackTrace();
          }catch (SecurityException e){
              e.printStackTrace();
          }catch (InstantiationException e){
              e.printStackTrace();
          }catch (IllegalAccessException e){
              e.printStackTrace();
          }catch (IllegalArgumentException e){
              e.printStackTrace();
          }catch (InvocationTargetException e){
              e.printStackTrace();
          }
可以使用以下代码创建对象的工具: ```java import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class ReflectionUtil { /** * 通过创建对象 * @param className 名 * @return 创建对象 */ public static Object createObject(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class<?> clazz = Class.forName(className); return clazz.newInstance(); } /** * 通过名和构造函数参数创建对象 * @param className 名 * @param args 构造函数参数 * @return 创建对象 */ public static Object createObject(String className, Object... args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<?> clazz = Class.forName(className); Class<?>[] parameterTypes = new Class[args.length]; for (int i = 0; i < args.length; i++) { parameterTypes[i] = args[i].getClass(); } Constructor<?> constructor = clazz.getConstructor(parameterTypes); return constructor.newInstance(args); } } ``` 其中,`createObject(String className)` 方法通过创建对象,`createObject(String className, Object... args)` 方法通过名和构造函数参数创建对象。使用时,只需要传入名和参数即可。注意,如果的构造函数是私有的,需要使用 `getDeclaredConstructor()` 方法获取构造函数,并设置 `setAccessible(true)` 来允许访问私有构造函数
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值