我是靠谱客的博主 悦耳高山,最近开发中收集的这篇文章主要介绍关于反射中.getDeclaredContructor()返回构造方法顺序的问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

 一、问题描述:
    在下面这段示例练习过程中,当使用注释中的if...else if...else的代码时,在eclips中运行始终在 System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");处死循环。
    二、问题查找:
    (1)认为是"constructor.setAccessible(true);"语句没有起到作用,debug后没有发现有任何问题;
    (2)认为是获取对象的语句.forName()没有获取到Class对象,改为.getClass()后问题依然;
    (3)书上说.getDeclaredConstructors()返回所有的构造方法,顺序是按照声明的顺序,也就是按照Example_01(String...string)、Example_01()和Example_01(String ,int)的顺序返回,为了验证,遍历输出了所有的构造方法,发现输出的顺序与书本说的顺序正好相反Example_01(String ,int)、Example_01()和Example_01(String...string);(哭死了,这是万万没想到的,一个礼拜的纠结终于有点眉目了),又看了下API文档,关于.getDeclaredConstructors()是这样说的:
public Constructor<?>[] getDeclaredConstructors()
throws SecurityException
Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object. These are public, protected, default (package) access, and private constructors. The elements in the array returned are not sorted and are not in any particular order. If the class has a default constructor, it is included in the returned array. This method returns an array of length 0 if this Class object represents an interface, a primitive type, an array class, or void.
      橙色 句子意思是,数组中返回的元素不会被分类或者按特定顺序排列,那我就纳闷了,为什么会和Example_01中构造方法定义的顺序正好相反呢?这个问题还需要有大神给解答一下。
    三、问题解决:
    发现顺序问题后,对if...else if...else的代码按照遍历时构造方法输出的顺序进行赋值,运行,问题解决;(乐死我了,哈哈哈)
    四、后续思考:
    (1)如果改变Example_01中3个构造方法的先后顺序,程序再次报错,原因是一样的,如何修改能让程序的运行不受构造方法顺序的影响?
    (2)根据3个构造方法的不同,主要是参数个数不同,增加了参数数量判断,然后进行赋值,修改后运行,问题解决。
    (3)如果构造方法中有参数数量相同的,例如在Example_01类中再增加一个构造方法Example_01(int, String),再次运行程序,问题再次出现。当一个重载方法被调用时,java通常在调用方法的参数和方法的自变量之间寻找匹配,但是会抛出IllegleArgumentException的异常,由于程序中对Exception进行了捕获,一旦出现异常,java就跳过另外一个赋值语句,直接运行到catch中去了。如何能够完美的解决这个问题还需要大神来解答一下了。

package major;

import java.lang.reflect.*;

public class Main_01 {

    private static Object[] parameters;

    public static void main(String[] args) throws Exception{
        //Example_01 example=new Example_01();                         //实例化一个Example_01
        Class exampleC=Class.forName("major.Example_01")    ;                        //获取Example_01的类型对象
        //Class exampleC=example.getClass();
        Constructor[] declaredConstructors=exampleC.getDeclaredConstructors();     //获取所有构造方法,按声明顺序返回
        //遍历所有的构造方法及其参数的个数并进行输出
        for (int i = 0; i < declaredConstructors.length; i++) {
            System.out.println(declaredConstructors[i].toString());
            System.out.println(declaredConstructors[i].getParameterTypes().length);
        }
        for(int i=0;i<declaredConstructors.length;i++){
            Constructor constructor=declaredConstructors[i];
            System.out.println(constructor.toString());
            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==0){
                        Object[] parameters = new Object[]{new String[]{"100","200","300"}};
                        example2=(Example_01)constructor.newInstance(parameters);
                    }else if(i==1)
                        example2=(Example_01)constructor.newInstance("7",5);
                    else{
                        example2=(Example_01)constructor.newInstance();
                    }*/
                    if(parameterTypes.length==1){
                        Object[] parameters = new Object[]{new String[]{"100","200","300"}};
                        example2=(Example_01)constructor.newInstance(parameters);
                    }else if(parameterTypes.length==2){
                        example2=(Example_01)constructor.newInstance("7",5);
                        // example2=(Example_01)constructor.newInstance(5,"7");
                    }else{
                        example2=(Example_01)constructor.newInstance();
                    }
                } catch (Exception e) {
                    System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
                    constructor.setAccessible(true);
                }
            }
            example2.print();
            System.out.println();
        }
    }
}

public class Example_01 {
    String s;
    int i, i2, i3;

    
private 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]);
        }

    }
   
 // 定义无参构造方法
    protected Example_01() {

    }

    // 定义有参构造方法
    public Example_01(String s, int i) {
        this.s = s;
        this.i = i;
    }



    public void print() {
        System.out.println("s=" + s);
        System.out.println("i=" + i);
        System.out.println("i2=" + i2);
        System.out.println("i3=" + i3);
    }
}

最后

以上就是悦耳高山为你收集整理的关于反射中.getDeclaredContructor()返回构造方法顺序的问题的全部内容,希望文章能够帮你解决关于反射中.getDeclaredContructor()返回构造方法顺序的问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部