访问构造方法(反射)

文章目录


前言

        Java的反射机制可以实现访问、检测和修改Java对象本身信息的功能,在java.lang.reflect包下提供此功能。可以使程序员更加深入地控制程序的运行过程。可以理解为随时调用某个类的某个构造方法,成员方法,属性。


一、反射是什么?

        Java反射是指在运行时(Runtime)动态获取和操作一个类的信息的能力。通过Java反射,可以在运行时获取类的属性、方法、构造函数等信息,并且可以动态调用这些属性和方法。

        Java反射允许程序在运行时动态加载、探知和使用编译时未知的类,对象,方法等,可以实现动态生成对象,动态调用方法,动态修改属性等功能。使用Java反射,可以实现一些框架和库的功能,例如Spring框架中的依赖注入、Hibernate框架中的ORM映射等。 

二、访问构造方法 

        Constructor类就是java反射机制的java.lang包下的具体方法。 

        使用Constructor对象可以访问相应的构造方法。获取Constructor对象需要使用以下的方法,返回Constructor类型的对象或数组。

1.Constructor对象的获取方法

获取构造方法的方法
方法功能描述
getConstructors()获取所有公有的构造方法
getConstructor(Class<?>...parameterTypes)获取对应的公有的构造方法
getDeclaredConstructors()获取所有的构造方法
getDeclaredConstructor(Class<?>...parameterTypes)获取指定的构造方法(无论是否私有)

        获取所有的构造方法,具体的一个例子,想要使用Constructor对象随时调用某类的构造方法,先实例化一个该类的对象,然后使用getClass()方法将该对象包装为原始类型Class,最后使用以上的方法获取所有的构造方法。

        实操展示:

Example example = new Example();
Class<? extends Example> exampleClass =example.getClass();            
Constructor constructor[] = exampleClass.getDeclaredConstructors();
//该constructor数组获取了example类的全部构造方法

         获取指定的构造方法,操作与以上步骤一致,唯一不同点在getDeclaredConstructor()的括号中填入 数据类型.Class 

        实操展示:

Example example = new Example();
Class<? extends Example> exampleClass =example.getClass();            
Constructor constructor = 
exampleClass.getDeclaredConstructor(String.class,int.class,int.class);
//该constructor对象操纵的构造方法数据类型为 String,int,int

        或者为:

Example example = new Example();
Class<? extends Example> exampleClass =example.getClass();            
Constructor constructor = 
exampleClass.getDeclaredConstructor(new Class{}[String.class,int.class,int.class]);
//该constructor对象操纵的构造方法数据类型为 String,int,int

2.Constructor方法的使用

Constructor类的常用方法
方法功能描述
isVarArgs()查看该构造方法是否允许带有可变数量的参数,如果允许返回ture,否则返回false
getParameterTypes()按照声明顺序以Class数组的形式获取该构造方法的各个参数的类型
getExceptionTypes()以Class数组的形式获取该构造方法可能抛出的异常
newInstance(Object...initarges)通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参数的构造方法
setAccessible(boolean flag)如果该构造方法的权限为private,flag值为ture的话,可以无视该权限
getModifiers()获取可以解析出该构造方法所采用修饰符的整数(private=0,protected=1,public=2)

        实操展示:

        原想调用的方法:

public class Example {
    String name=null;
    int age=0;
    int id=0;

    public Example(){}

    @SuppressWarnings("unused")
    private Example(int id){
        this.id=id;
    }

    public Example(String name,int age,int id){
        this.name=name;
        this.age=age;
        this.id=id;
    }

    
    public Example(String...strings){
        if(strings.length>0){
            this.name=strings[0];
        }
        if(strings.length>1){
            this.age=Integer.valueOf(strings[1]);
        }
        if(strings.length>2){
            this.id=Integer.valueOf(strings[2]);
        }
    }

    public void input(){
        System.out.println("姓名:"+name+" 年龄:"+age+" id="+id);
    }
}

        该Example类有四个构造方法,将在下面的Demo类中,使用Constructor类的常用方法,逐一调用,并输出各个构造方法的信息。

import java.lang.reflect.Constructor;

public class Demo{
    public static void main(String[] args) {
        Example person = new Example("张三", 18,101);
        Class<? extends Example> personC =person.getClass();
        @SuppressWarnings("rawtypes")
        Constructor[] declaredConstructors = personC.getDeclaredConstructors();
        for(int i=0;i<declaredConstructors.length;i++){
            Constructor<?> constructor = declaredConstructors[i];
            
            System.out.println("该类的名称:"+constructor.getName());
            //获取该构造方法的名称
            
            System.out.println("查看是否允许带有可变数量的参数:"+constructor.isVarArgs());
            //获取该构造方法的参数是否为可变的

            System.out.println("该构造方法的参数类型依次为:");
            @SuppressWarnings("rawtypes")
            Class type[]=constructor.getParameterTypes();
            if(type.length==0){
                System.out.println("该构造方法是无参的");
            }
            for(int j=0;j<type.length;j++){
                System.out.println(type[j]);
            }
            //获取该构造方法的参数类型

            System.out.println("该构造方法可能抛出的异常类型:");
            @SuppressWarnings("rawtypes")
            Class excpetion[]= constructor.getExceptionTypes();
            if(excpetion.length==0){
                System.out.println("无");
            }
            for(int j=0;j<excpetion.length;j++){
                System.out.println(excpetion[j]);
            }
            //获取该构造方法可能抛出的异常类型

             Example example =null;
             while (example==null) {
                try {
                    if (i==0) {
                        Object contect[] = new Object[]{new String[]{"王五","30","104"}};
                        example=(Example)constructor.newInstance(contect);  //此方法所填值为object对象,newInstance方法不接受原始类型,例如String,需要封装成Object类
                    }else if(i==1){
                        example=(Example)constructor.newInstance("李四",20,102);
                    }else if(i==2){
                        example=(Example)constructor.newInstance(103);
                    }else if (i==3) {
                        example=(Example)constructor.newInstance();
                    }   
                    //实例化各个构造方法
                } catch (ClassCastException e) {
                    e.printStackTrace();
                } catch (Exception e){
                    //如果创建对象时异常,方法为私有,运行以下方法
                    constructor.setAccessible(true);
                    e.printStackTrace();
                }
            } 
            if (example!=null) {
                example.input();
            }
            System.out.println("-------------------------------------");
        }
    }
}

        运行结果: 

        如上图当我们创建好一个该类的对象后,再转换为Constructor对象,就可以随时使用调用其newInstance()方法调用该类的构造方法,在代码运行的过程中实现动态调整数值。 

        补充:

Modifier类中的常用解析方法
静态方法功能描述
isPublic(int mod)查看是否被public修饰符修饰,如果是则返回true,否则返回false
isProtected(int mod)查看是否被protected修饰符修饰,如果是则返回true,否则返回false
isPrivate(int mod)查看是否被private修饰符修饰,如果是则返回true,否则返回false
isStatic(int mod)查看是否被static修饰符修饰,如果是则返回true,否则返回false
isFinal(int mod)查看是否被final修饰符修饰,如果是则返回true,否则返回false
toString(int mod)以字符串的形式返回所有修饰符

        举个例子说明如何使用。例子:判断contructor对象所代表的构造方法是否被final修饰符修饰,以及以字符串的形式获得该构造方法的所有修饰符的常写代码如下:

int modifiers = constructor.getModifiers();
//获取该constructor对象的构造方法的限制符整数值
boolean isEmbellishByPrivate = Modifier.isFinal(modifiers);
//是否被final修饰符修饰
String embellishment = Modifier.toString(modifiers);
//以字符串的形式获得该构造方法

总结

        以上就是今天要讲的内容,本文仅仅简单介绍了访问构造方法的使用,而反射提供了大量能使我们快速便捷地处理数据的函数和方法,指正的内容欢迎在评论区中留言。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵果森森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值