A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

import java.lang.reflect.Constructor;
import java.lang.reflect.*;

public class Example_01 {
        String s;
        int i, i2, i3;
        private Example_01() {
        }
        protected Example_01(String s, int i) {
                this.s = s;
                this.i = i;
        }
        public Example_01(String... strings) throws NumberFormatException {
                if (0 < strings.length)
                        i = Integer.valueOf(strings[0]);
                if (1 < strings.length)
                        i2 = Integer.valueOf(strings[1]);
                if (2 < strings.length)
                        i3 = Integer.valueOf(strings[2]);
        }
        public void print() {
                System.out.println("s=" + s);
                System.out.println("i=" + i);
                System.out.println("i2=" + i2);
                System.out.println("i3=" + i3);
        }
        public static void main(String[] args) {

                Example_01 example = new Example_01("10", "20", "30");
                Class<? extends Example_01> exampleC = example.getClass();

                Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();
                for (int i = 0; i < declaredConstructors.length; i++) {
                        Constructor<?> constructor = declaredConstructors;
                        System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());
                        System.out.println("该构造方法的入口参数类型依次为:");
                        Class[] parameterTypes = constructor.getParameterTypes();
                        for (int j = 0; j < parameterTypes.length; j++) {
                                System.out.println(" " + parameterTypes[j]);
                        }
                        System.out.println("该构造方法可能抛出的异常类型为:");
                        Class[] exceptionTypes = constructor.getExceptionTypes();
                        for (int j = 0; j < exceptionTypes.length; j++) {
                                System.out.println(" " + exceptionTypes[j]);
                        }
                        Example_01 example2 = null;
                        while (example2 == null) {
                                try {
                                        if (i == 2)
                                                example2 = (Example_01) constructor.newInstance();
                                        else if (i == 1)
                                                example2 = (Example_01) constructor.newInstance("7", 5);
                                        else {
                                                Object[] parameters = new Object[] { new String[] {
                                                                "100", "200", "300" } };
                                                example2 = (Example_01) constructor
                                                                .newInstance(parameters);
                                        }
                                } catch (Exception e) {
                                        System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
                                        constructor.setAccessible(true);
                                }
                        }
                        if(example2!=null){
                        example2.print();
                        System.out.println();
                        }
                }

        }

}
运行结果:
查看是否允许带有可变数量的参数:true
该构造方法的入口参数类型依次为:
class [Ljava.lang.String;
该构造方法可能抛出的异常类型为:
class java.lang.NumberFormatException
s=null
i=100
i2=200
i3=300

查看是否允许带有可变数量的参数:false
该构造方法的入口参数类型依次为:
class java.lang.String
int
该构造方法可能抛出的异常类型为:
s=7
i=5
i2=0
i3=0

查看是否允许带有可变数量的参数:false
该构造方法的入口参数类型依次为:
该构造方法可能抛出的异常类型为:
s=null
i=0
i2=0
i3=0

大神讲讲这个程序是怎么运行的?步骤。先行谢过

3 个回复

倒序浏览
  1. 不好好看视频,有点蛋疼

  2. import java.lang.reflect.*;

  3. public class Example_01 {
  4.         /*
  5.          * 定义4个成员变量
  6.          */
  7.         String s;
  8.         int i, i2, i3;

  9.         // 无参构造函数
  10.         @SuppressWarnings("unused")
  11.         private Example_01() {
  12.         }

  13.         // 参数类型为 String和int 的构造函数
  14.         protected Example_01(String s, int i) {
  15.                 this.s = s;
  16.                 this.i = i;
  17.         }

  18.         // String类型可变参数的构造函数,且抛出异常
  19.         public Example_01(String... strings) throws NumberFormatException {
  20.                 /*
  21.                  * 下面是获取相应位置的参数
  22.                  */
  23.                 if (0 < strings.length)
  24.                         i = Integer.valueOf(strings[0]);
  25.                 if (1 < strings.length)
  26.                         i2 = Integer.valueOf(strings[1]);
  27.                 if (2 < strings.length)
  28.                         i3 = Integer.valueOf(strings[2]);
  29.         }

  30.         // 输出成员变量值的函数
  31.         public void print() {
  32.                 System.out.println("s=" + s);
  33.                 System.out.println("i=" + i);
  34.                 System.out.println("i2=" + i2);
  35.                 System.out.println("i3=" + i3);
  36.         }

  37.         // 主函数
  38.         public static void main(String[] args) {

  39.                 // 创建一个Example_01的对象,且调用的是可变参数构造函数
  40.                 Example_01 example = new Example_01("10", "20", "30");
  41.                 /*
  42.                  * 通过example对象获取Example_01的字节码文件,目的是为了下面反射用
  43.                  * 因为反射的前提就是拿到需要反射类的Class
  44.                  * 这里泛型限定可以不管
  45.                  */
  46.                 Class<? extends Example_01> exampleC = example.getClass();

  47.                 /*
  48.                  * 得到Example_01中的所有方法,这里用的是Declared,可以获取任何类型
  49.                  * 包括私有和保护的(如果有的话)
  50.                  */
  51.                 Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();

  52.                 // 遍历所有的构造函数
  53.                 for (int i = 0; i < declaredConstructors.length; i++) {
  54.                         // 得到相应的构造函数,并对其进行操作
  55.                         Constructor<?> constructor = declaredConstructors[i];
  56.                         // 用isVarArgs方法判断构造函数时候有可变参数,返回类型Boolean,并打印
  57.                         System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());

  58.                         /*
  59.                          * getParameterTypes得到构造函数的参数类型,由于可能不止一个参数,所以返回类型为数组
  60.                          * 并通过for循环打印出各参数类型
  61.                          */
  62.                         System.out.println("该构造方法的入口参数类型依次为:");
  63.                         Class[] parameterTypes = constructor.getParameterTypes();
  64.                         for (int j = 0; j < parameterTypes.length; j++) {
  65.                                 System.out.println(" " + parameterTypes[j]);
  66.                         }

  67.                         /*
  68.                          * getExceptionTypes得到构造函数抛出异常类型,同样由于抛出异常
  69.                          * 可能不止一个所以返回的也是数组类型
  70.                          * 也是通过for循环打印所有异常
  71.                          */
  72.                         System.out.println("该构造方法可能抛出的异常类型为:");
  73.                         Class[] exceptionTypes = constructor.getExceptionTypes();
  74.                         for (int j = 0; j < exceptionTypes.length; j++) {
  75.                                 System.out.println(" " + exceptionTypes[j]);
  76.                         }

  77.                         /*
  78.                          * 下面是建立相应构造函数的实例对象
  79.                          * 这里需要注意的是,上面在获取构造函数时,返回数组中的元素没有排序,也没有任何特定的顺序。
  80.                          * 所以是按照上面遍历输出结果决定的个构造函数的顺序 这里的i判断,
  81.                          * 对应上面相应的输出,可以看你的输出结果
  82.                          */
  83.                         Example_01 example2 = null;
  84.                         while (example2 == null) {
  85.                                 try {
  86.                                         if (i == 2)
  87.                                                 /*
  88.                                                  * 这个空参构造函数,没有为任何成员变量赋值,所以输出都为其初始值null或0
  89.                                                  */
  90.                                                 example2 = (Example_01) constructor.newInstance();
  91.                                         else if (i == 1)
  92.                                                 /*
  93.                                                  * 这个固定参数的构造函数中,为成员变量s和i分别赋值,
  94.                                                  * 且值的 大小为构造时传入值,这里分别为7和5
  95.                                                  * 其他为默认值
  96.                                                  */
  97.                                                 example2 = (Example_01) constructor.newInstance("7", 5);
  98.                                         else {
  99.                                                 /*
  100.                                                  * 这里是可变参数列表,根据上面的构造函数可以看出,他分别为i,i2,i3赋值
  101.                                                  * 这里分别为100,200,300 s还是默认的null
  102.                                                  */
  103.                                                 Object[] parameters = new Object[] { new String[] {
  104.                                                                 "100", "200", "300" } };
  105.                                                 example2 = (Example_01) constructor
  106.                                                                 .newInstance(parameters);
  107.                                         }
  108.                                 } catch (Exception e) {
  109.                                         System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
  110.                                         constructor.setAccessible(true);
  111.                                 }
  112.                         }
  113.                         // 这里是调用print方法,打印所有成员变量的值,上面已经说了值为多少
  114.                         if (example2 != null) {
  115.                                 example2.print();
  116.                                 System.out.println();
  117.                         }
  118.                 }

  119.         }

  120. }

复制代码

回复 使用道具 举报

为什么直接是从参数多的执行的?
回复 使用道具 举报
ZHENGYUNJUN 发表于 2017-9-6 14:58
为什么直接是从参数多的执行的?

我也想知道啊!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马