Java通过反射访问构造方法
为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个 Constructor 类型的对象或者数组。
getConstructors()getConstructor(Class<?>…parameterTypes)getDeclaredConstructors()getDeclaredConstructor(Class<?>...parameterTypes)
如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。例如,访问一个入口参数类型依次为 int 和 String 类型的构造方法,下面的两种方式均可以实现。
objectClass.getDeclaredConstructor(int.class,String.class);objectClass.getDeclaredConstructor(new Class[]{int.class,String.class});
创建的每个 Constructor 对象表示一个构造方法,然后利用 Constructor 对象的方法操作构造方法。
Constructor类的常用方法
方法名称 | 说明 |
---|---|
isVarArgs() | 查看该构造方法是否允许带可变数量的参数,如果允许,返回 true,否则返回false |
getParameterTypes() | 按照声明顺序以 Class 数组的形式获取该构造方法各个参数的类型 |
getExceptionTypes() | 以 Class 数组的形式获取该构造方法可能抛出的异常类型 |
newInstance(Object … initargs) | 通过该构造方法利用指定参数创建一个该类型的对象,如果未设置参数则表示采用默认无参的构造方法 |
setAccessiable(boolean flag) | 如果该构造方法的权限为 private,默认为不允许通过反射利用 netlnstance()方法创建对象。如果先执行该方法,并将入口参数设置为 true,则允许创建对象 |
getModifiers() | 获得可以解析出该构造方法所采用修饰符的整数 |
通过 java.lang.reflect.Modifier 类可以解析出 getMocMers() 方法的返回值所表示的修饰符信息。在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以字符串的形式获得所有修饰符。
Modifier类的常用方法
静态方法名称 | 说明 |
---|---|
isStatic(int mod) | 如果使用 static 修饰符修饰则返回 true,否则返回 false |
isPublic(int mod) | 如果使用 public 修饰符修饰则返回 true,否则返回 false |
isProtected(int mod) | 如果使用 protected 修饰符修饰则返回 true,否则返回 false |
isPrivate(int mod) | 如果使用 private 修饰符修饰则返回 true,否则返回 false |
isFinal(int mod) | 如果使用 final 修饰符修饰则返回 true,否则返回 false |
toString(int mod) | 以字符串形式返回所有修饰符 |
下列代码判断对象 con 所代表的构造方法是否被 public 修饰,以及以字符串形式获取该构造方法的所有修饰符。
int modifiers = con.getModifiers(); // 获取构造方法的修饰符整数
boolean isPublic = Modifier.isPublic(modifiers); // 判断修饰符整数是否为public
string allModifiers = Modifier.toString(modifiers);
示例如何调用 Constructor 类的方法获取构造方法的信息。
1 . 首先创建一个 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);}
}
2 . 编写测试类 Test,在该类的 main() 方法中通过反射访问 Book 类中的所有构造方法,并将该构造方法是否带可变类型参数、入口参数类型和可能拋出的异常类型信息输出到控制台。
Test 类的代码如下:
public class Test {public static void main(String[] args) {// 获取动态类BookClass 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) {// 通过执行带两个参数的构造方法实例化book1book1 = (Book) con.newInstance("Java 教程", 10);} else if (i == 2) {// 通过执行默认构造方法实例化book1book1 = (Book) con.newInstance();} else {// 通过执行可变数量参数的构造方法实例化book1Object[] 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");}}
}
3 . 运行测试类 Test,当通过反射访问默认构造方法 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通过反射访问成员变量
通过下列任意一个方法访问成员变量时将返回 Field 类型的对象或数组. getFields()getField(String name)getDeclaredFields()getDeclaredF ...
- [Java基础]反射获取构造方法并使用练习
Student类代码如下: package ClassObjectPack;public class Student {private String name;int age;public Strin ...
- [Java基础]反射获取构造方法并使用
代码如下: package ClassObjectPack;import java.lang.annotation.Annotation; import java.lang.reflect.Const ...
- JAVA创建一个私有域_使用java基础反射访问私有域、方法和构造函数
1.类 public class ConfigData { private Map configs = null; private final String fileName = "conf ...
- java 反射 成员变量_java使用反射访问成员变量的值示例
本文实例讲述了java使用反射访问成员变量的值.分享给大家供大家参考,具体如下: 一 代码 import java.lang.reflect.*; class Person { private Str ...
- Java反射获取构造方法
[通过反射获取构造方法并使用] 获取构造方法 public Constructor[] getConstructors():所有公共构造方法 public Constructor[] getDecla ...
- sqlite字段是否存在_学习廖雪峰的JAVA教程---反射(访问字段)
对任意的一个Object实例,只要我们获取了它的Class,就可以获取它的一切信息. 我们先看看如何通过Class实例获取字段信息.Class类提供了以下几个方法来获取字段: Field getFie ...
- java 反射 main_java – 通过反射访问main方法中的局部变量
Since main is static, is it possible to access instanceOfB in order to access the value of _nonStati ...
- java反射访问室友属性_如何与家人,室友和客人共享HomeKit访问权限
java反射访问室友属性 What's the point of having a house of the future if your family members, roommates, or ...
最新文章
- CoordinatorLayout 和 AppBarLayout 实现折叠效果 底部带阴影的处理方法
- android studio 的中文网站
- 树莓派配置路由_树莓派安装Ubuntu 20.04 LTS并配置
- Mxnet - Understanding weight shape for Dense Layer MXNET权重参数形状的疑惑(内部设计形式行列谁在前不用管,多个转置运算而已)
- 几种特征选择方法的比较,孰好孰坏?
- 网站如何接入微信支付功能?微信支付详细教程它来了(建议收藏)
- 垂直居中重要方法理解---重点是方法三
- 解决 IntelliJ IDEA 安装后界面消失,再次打开后界面不动
- qDebug格式化输出类型
- archives_do.php,织梦后台文章管理中增加批量添加tag标签功能
- Linux CGLIB升级,cglib升级建议
- 几个阿里,美团,腾讯大佬的公众号!超级变态!
- 765. 情侣牵手--(每日一难phase2--day14)
- 实用的图片批量压缩优化工具
- 2020年中国不支持苹果_苹果2020年9月事件提示
- HTML两张图片翻转,canvas实现图片镜像翻转的2种方式
- 基于FPGA的卷积神经网络加速器(绪论)
- 怎么把电脑上的文件备份到百度网盘?
- 推荐一款免费的数据库管理工具,比Navicat还要好用,功能还很强大!
- 信息安全意识-密码安全
热门文章
- 桔子浏览器电脑版收藏夹位置在哪里 收藏夹位置路径
- 钉钉项目任务怎么添加审批表单
- windows7电脑怎么永久关闭广告
- SAP ABAP 打印(smartforms方式)
- Java中switch参数传null会引起异常——Java 语法糖
- postman如何发送application/json类的post请求
- 解决MongoDB Compass
- mysql区间段_解决针对MySQL中对于某一个区间段范围的数据更新的情况
- 用计算机弹奏曲子童年,5.这首曲子使我想起了我的童年.十.书面表达现在.计算机游戏非常盛行.这是一件好事还是一件坏事?请你用英语写一篇短文来陈述自己的观点.并说明理由.字数:80-120....
- 计算机应用常用的30个函数,Excel中常用函数的使用