java通过反射访问构造方法详解

KLQ 2020-08-24 14:34:25 java常见问答 6419

之前给大家对java反射机制做了一下比较详细的介绍,下面要给大家介绍的就是java通过反射访问构造方法方面的内容,一起来了解一下吧。

为了可以动态获取对象构造方法的信息,最开始的话就要通过下面方法之一创建一个Constructor类型的对象或者数组。

java通过反射访问构造方法

假如,是访问指定的构造方法,那么就要根据该构造方法的入口参数的类型来访问。

例:

访问一个入口参数类型依次为int和String类型的构造方法。

下面的两种方式都能够实现:

objectClass.getDeclaredConstructor(int.class,String.class);
objectClass.getDeclaredConstructor(new Class[]{int.class,String.class});

创建的每个Constructor对象表示一个构造方法,之后,利用Constructor对象的方法操作构造方法。

下面是Constructor类的常用方法:

Constructor类的常用方法

通过java.lang.reflect.Modifier类能够解析出getMocMers()方法的返回值所表示的修饰符信息。

在这个类当中,提供了一系列用来解析的静态方法,也就是可以查看是否被指定的修饰符修饰,还可以字符串的形式获得所有修饰符。

下面的话就列出了Modifier类的常用静态方法。

Modifier类的常用静态方法

例:

下列代码判断对象con所代表的构造方法是否被public修饰,以及以字符串形式获取该构造方法的所有修饰符。

int modifiers = con.getModifiers(); // 获取构造方法的修饰符整数
boolean isPublic = Modifier.isPublic(modifiers); // 判断修饰符整数是否为public 
string allModifiers = Modifier.toString(modifiers);

示例:

下面的话,就通过一个例子来演示怎样调用Constructor类的方法获取构造方法的信息。

首先的话要先创建一个Book类表示图书信息,在这个类当中声明一个String型变量表示图书名称,两个int型变量分别表示图书编号和价格,并提供3个构造方法。

Book类代码:

public class Book
{
    String name; // 图书名称
    int id, price; // 图书编号和价格
    // 空的构造方法
    private Book()
    {}
    // 带两个参数的构造方法
    protected Book(String _name, int _id)
    {
        this.name = _name;
        this.id = _id;
    }
    // 带可变参数的构造方法
    public Book(String...strings) throws NumberFormatException
    {
        if (0 < strings.length)
            id = Integer.valueOf(strings[0]);
        if (1 < strings.length)
            price = Integer.valueOf(strings[1]);
    }
    // 输出图书信息
    public void print()
    {
        System.out.println("name=" + name);
        System.out.println("id=" + id);
        System.out.println("price=" + price);
    }
}

编写测试类Test01,在这个类的main()方法当中通过反射访问Book类当中的所有构造方法,并将这个构造方法是否带可变类型参数、入口参数类型和可能拋出的异常类型信息输出到控制台。

Test01类的代码:

public class Test01
{
    public static void main(String[] args)
    {
        // 获取动态类Book
        Class book = Book.class;
        // 获取Book类的所有构造方法
        Constructor[] declaredContructors = book.getDeclaredConstructors();
        // 遍历所有构造方法
        for (int i = 0; i < declaredContructors.length; i++)
        {
            Constructor con = declaredContructors[i];
            // 判断构造方法的参数是否可变
            System.out.println("查看是否允许带可变数量的参数:" + con.isVarArgs());
            System.out.println("该构造方法的入口参数类型依次为:");
            // 获取所有参数类型
            Class[] parameterTypes = con.getParameterTypes();
            for (int j = 0; j < parameterTypes.length; j++)
            {
                System.out.println(" " + parameterTypes[j]);
            }
            System.out.println("该构造方法可能拋出的异常类型为:");
            // 获取所有可能拋出的异常类型
            Class[] exceptionTypes = con.getExceptionTypes();
            for (int j = 0; j < exceptionTypes.length; j++)
            {
                System.out.println(" " + parameterTypes[j]);
            }
            // 创建一个未实例化的Book类实例
            Book book1 = null;
            while (book1 == null)
            {
                try
                { // 如果该成员变量的访问权限为private,则拋出异常
                    if (i == 1)
                    {
                        // 通过执行带两个参数的构造方法实例化book1
                        book1 = (Book) con.newInstance("Java 教程", 10);
                    }
                    else if (i == 2)
                    {
                        // 通过执行默认构造方法实例化book1
                        book1 = (Book) con.newInstance();
                    }
                    else
                    {
                        // 通过执行可变数量参数的构造方法实例化book1
                        Object[] parameters = new Object[]
                        {
                            new String[]
                            {
                                "100"
                                , "200"
                            }
                        };
                        book1 = (Book) con.newInstance(parameters);
                    }
                }
                catch (Exception e)
                {
                    System.out.println("在创建对象时拋出异常,下面执行 setAccessible() 方法");
                    con.setAccessible(true); // 设置允许访问 private 成员
                }
            }
            book1.print();
            System.out.println("=============================\n");
        }
    }
}

运行测试类Test01,在通过反射访问默认构造方法Book()的时候,可以看到下面的输出:

查看是否允许带可变数量的参数:false
该构造方法的入口参数类型依次为:
该构造方法可能抛出的异常类型为:
在创建对象时抛出异常,下面执行setAccessible()方法
name = null
id = 0
price = 0
=============================

在通过反射访问两个参数的构造方法Book(String_name,int_id)的时候,会看到下面的输出:

查看是否允许带可变数量的参数:false
该构造方法的入口参数类型依次为:
class java.lang.String
int
该构造方法可能抛出的异常类型为:
在创建对象时抛出异常,下面执行setAccessible()方法
name = null
id = 0
price = 0
=============================

在通过反射访问可变参数数量的构造方法Book(String...strings)的时候,会看到下面的输出:

查看是否允许带可变数量的参数:true
该构造方法的入口参数类型依次为:
class java.lang.String;
该构造方法可能抛出的异常类型为:
class java.lang.String;
在创建对象时抛出异常,下面执行setAccessible()方法
name = null
id = 0
price = 0
=============================

以上的内容你都了解了吗?更多和java反射相关的java基础知识,可以继续的关注奇Q工具网来进行了解哦。

推荐阅读:

java反射机制API详解

java反射机制是什么?概念功能优缺点详细介绍

java反射技术是什么?有什么作用?