通过反射访问构造方法(学习笔记)

首先先来看一下反射的概念
主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
简言之就是通过反射机制,程序在运行时能够获取自身的信息并且修改;而且是类中有什么信息,它就可以获得什么信息,不过前提是得知道类的名字,要不就没有后文了

接下来我们分别来看一下反射机制可以访问到的主要描述信息和具体用法吧

首先我们要先了解,所有类的对象其实都是Class的实例。因此访问描述信息,必须通过Class类,我们看怎么用

//第一种方式:  
Class c1 = Class.forName("Employee");  

//第二种方式:  
//java中每个类型都有class 属性.  
Class c2 = Employee.class;  

//第三种方式:  
//java语言中任何一个java对象都有getClass 方法  
Employee e = new Employee();  
Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)  

OK,创建好Class类之后呢,我们就可以通过其来返回该对象的描述信息了,我们先来看构造方法中的信息;

构造方法

我们首先需要声明通过以下方法访问构造方法,将返回Constructor类型的对象或数组。每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法;


 getConstructor()  此方法获得所有权限为public的构造方法
 getConstructor(Class<?>...parameterTypes) 获得权限为public的执行构造方法
 getDelcareConstructor() 获得所有构造方法,按指定顺序返回
 getDelcareConstructor(Class<?>...parameterTypes) 获得指定构造方法

如果是访问指定的构造方法呢,就需要根据构造方法的入口参数的类型来访问。例如,访问一个入口参数类型依次为String和int型的构造方法,通过下面两种方式均可实现

objectClsss.getConstructor(String.class,int.class);
objectClsss.getConstructor(new Class[]{String.class,int.class});

接下来我们介绍一下Constructor类中提供的方法,我们先看代码;

public class Example_01 {
    String s;
    int i,i2,i3;
    @SuppressWarnings("unused")
    private Example_01(){

    }
    protected Example_01(String s,int i){
        this.s=s;
        this.i=i;
    }
    public Example_01(String... strings) throws NumberFormatException{
        if (strings.length>0) {
            i=Integer.valueOf(strings[0]);
        }
        if (strings.length>1) {
            i2=Integer.valueOf(strings[1]);
        }
        if (strings.length>2) {
            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);
    }

}

上述是一个简单的类,里面创建了三个构造方法,分别用private,protect,public修饰符来修饰

接下来我们通过反射机制来访问上述类中的构造方法

public class test {
    public static void main(String[] args) throws SecurityException, NoSuchMethodException {
        Example_01 example=new Example_01();//创建一个Exampl_01对象
        Class  exampleC=example.getClass();//创建Class类对象,通过getClass方法返回
        Constructor[] declareConstractors=exampleC.getDeclaredConstructors();
        //获得所有构造方法形成的对象数组
        for (int i = 0; i < declareConstractors.length; i++) {  //遍历Constructor对象
            Constructor constructor=declareConstractors[i];
            System.out.println("构造方法中是否含有可变数量的参数:"+constructor.isVarArgs());
                //调用isVarAges方法查看该构造方法是否允许带有可变数量的参数
            System.out.println("每个构造方法传入的参数类型:");
            //通过getParameterTypes()方法获得每个构造方法传入参数的类型;返回为Class类
            Class[] parameterTypes=constructor.getParameterTypes();
            for (int j = 0; j < parameterTypes.length; j++) {
                System.out.println(""+parameterTypes[j]);
            }
            System.out.println("可能传出的错误:");
            Class[] exceptionTypes=constructor.getExceptionTypes();
            //通过getExceptionTypes()方法取得可能返回的异常信息,返回为Class类
            for (int j = 0; j < exceptionTypes.length; j++) {
                System.out.println(""+exceptionTypes[j]);
            }
            Example_01 example2=null;//创建空的Example_02对象;
            while(example2==null){
                try {
                    if(i==0){
                        example2=(Example_01)constructor.newInstance();//利用newInstance()方法实例化一个对象
                    }
                    else if (i==1) {
                        example2=(Example_01)constructor.newInstance("100",100);
                    }
                    else if (i==2) {
                        example2=new Example_01(new String[]{"100","200","100"});

                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    System.out.println("抛出异常解决方法");
                    constructor.setAccessible(true);//定义可以访问私有构造方法

                }
            }
            example2.print();
            System.out.println();

        }

    }

}

我们来看代码输出

构造方法中是否含有可变数量的参数:false
每个构造方法传入的参数类型:
可能传出的错误:
抛出异常解决方法
s=null
i=0
i2=0
i3=0

构造方法中是否含有可变数量的参数:false
每个构造方法传入的参数类型:
class java.lang.String
int
可能传出的错误:
s=100
i=100
i2=0
i3=0

构造方法中是否含有可变数量的参数:true
每个构造方法传入的参数类型:
class [Ljava.lang.String;
可能传出的错误:
class java.lang.NumberFormatException
s=null
i=100
i2=200
i3=100

通过以上代码我们可以看出Constructor类中主要有一下几种方法

  • isVarAges() 查看构造方法是否允许带有可变数量的参数,如果允许则返回true,否则返回false;
  • getParameterTypes() 方法获得每个构造方法传入参数的类型;返回为Class类数组
  • getExceptionTypes()方法取得可能返回的异常信息,返回为Class类数组
  • newInstance(Objectinitarges) 通过该构造方法利用指定参数创建一个该类的对象。如果未设置参数则表示采用默认无参数的构造方法
  • setAccessible(boolean flag) 允许创建构造方法不是public修饰的

    以上就是我对于JAVA反射中访问构造方法内容的理解,如果有什么需要改进的地方,请在评论区留言,谢谢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值