Java反射机制demo(三)—获取类中的构造函数

1,获取类中所有的构造函数

如下面的代码中所示,这个类中显式的构造函数有五个。

空构造:

  • public UserInfo()

带参构造有四个:

  • public UserInfo(int userId)
  • private UserInfo(String name)
  • protected UserInfo(int userId, String name)
  • public UserInfo(int userId, String name, int age)

注意 他们的访问修饰符。

 package com.aaron.reflect;

 public class UserInfo{
private int userId;
private String name;
private int age; public UserInfo(){} public UserInfo(int userId){
    this.userId = userId;
}
     private UserInfo(String name){
         this.name = name;
     } public UserInfo(int userId, String name, int age) {
super();
this.userId = userId;
this.name = name;
this.age = age;
} public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "UserInfo [userId=" + userId + ", name=" + name + ", age=" + age + "]";
} }

我们可以使用Class类中的Constuctor<?>[] getConstructors()方法,来获得这个类的构造函数。

JDK API文档里,对这个方法的描述如下:

返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。如果该类没有公共构造方法,或者该类是一个数组类,或者该类反映一个基本类型或 void,则返回一个长度为 0 的数组。 注意,此方法返回 Constructor<T> 对象的数组(即取自此类构造方法的数组)时,此方法的返回类型是 Constructor<?>[]不是 预期的 Constructor<T>[]。此少量信息的返回类型是必需的,因为从此方法返回之后,该数组可能被修改以保存不同类的 Constructor 对象,而这将违反 Constructor<T>[] 的类型保证。

总之,返回了表示此类公共构造方法的Constructor对象数组。注意,这里是公共构造方法。

测试类的代码如下:

  

Constuctor<?>[] getConstructors()

package com.aaron.reflect;

import java.lang.reflect.Constructor;

public class Demo2 {
public static void main(String[] args) {
Class<?> c = UserInfo.class;//获取Class对象 Constructor<?> cons[] = c.getConstructors();//获取构造函数的数组
//打印
for (Constructor<?> constructor : cons) {
System.out.println(constructor);
}
}
}

运行结果如下:

public com.aaron.reflect.UserInfo()
public com.aaron.reflect.UserInfo(int,java.lang.String,int)
public com.aaron.reflect.UserInfo(int)

 运行的结果打印出了所有显式声明的,而且是公共的构造函数。

但是,这个顺序和我们类里的定义顺序是不一样的,因此,从这个方法精准地定位一个构造函数是不可取的。真的乱序的吗?API里没有提到。但是,另外一个方法的文档中提到了。这个方法是

Constuctor<?>[] getDeclaredConstructors()

这个方法返回Constructor对象的一个数组,这些对象包含了Class对象所表示的类中的所有构造方法。它们分别是公共,保护,默认(包),和私有构造。

返回数组中的元素没有排序,也没有任何特定的顺序。

如果该类存在一个默认构造方法,则它包含在返回的数组中。如果此Class对象表示一个接口,一个基本类型,一个数组类或者void,则这个方法返回一个长度为0的数组。

测试类:

package com.aaron.reflect;

import java.lang.reflect.Constructor;

public class Demo2 {
public static void main(String[] args) {
Class<?> c = UserInfo.class;//获取Class对象 Constructor<?> cons[] = c.getDeclaredConstructors();
//打印
for (Constructor<?> constructor : cons) {
System.out.println(constructor);
}
}
}

  运行结果:

public com.aaron.reflect.UserInfo()
public com.aaron.reflect.UserInfo(int,java.lang.String,int)
public com.aaron.reflect.UserInfo(int)
private com.aaron.reflect.UserInfo(java.lang.String)
protected com.aaron.reflect.UserInfo(int,java.lang.String)

2,调用构造方法生成实例

Constructor<T> getConstructor(Class<?>... parameterTypes)

package com.aaron.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; public class Demo2 {
public static void main(String[] args) {
Class<?> c = UserInfo.class;//获取Class对象
try {
Constructor<?> constructor = c.getConstructor(int.class);//只有使用类字面常量才能够获取基本类型的Class对象
UserInfo userInfo = (UserInfo) constructor.newInstance(1);//构造实例
System.out.println(userInfo);
} catch (Exception e) {
e.printStackTrace();
}
}
}

  注意其中的注释,只有使用类字面常量才能获得int这种基本类型的Class对象。

而Integer.class和int.class所表示的Class必然不同,因为一个是泛型一个是基本类型。Integer继承了java.lang.Number,而Number继承了java.lang.Object。

下面给出运行结果。

UserInfo [userId=1, name=null, age=0]

  

  

Java反射机制demo(三)—获取类中的构造函数的更多相关文章

  1. Java反射机制demo(五)—获得并调用一个类中的方法

    Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...

  2. Java反射机制demo(四)—获取一个类的父类和实现的接口

    Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 ...

  3. Java反射机制demo(一)—实例化Class对象,并获得其他类包名和类型

    Java反射机制demo(一)——实例化Class对象,通过对象获得包名和类型 使用Java中的 本地类作为实验对象,避免自定义的类带来的一些不便. public static void main(S ...

  4. Java反射机制demo(二)—通过Class实例化任意类的对象

    Java反射机制demo(二)—通过Class实例化任意类的对象 上一章节中,实例化了Class类对象的实例,这个部分的demo展示了如何使用Class对象的实例去获得其他类的对象的实例. 任意一个类 ...

  5. Java反射机制demo(六)—获得并操作一个类的属性

    Java反射机制demo(六)—获得并操作一个类的属性 获得并操作一个类的属性?! 不可思议啊,一个类的属性一般都是私有成员变量啊,private修饰符啊! 但是毫无疑问,这些东西在Java的反射机制 ...

  6. Java反射机制demo(七)—反射机制与工厂模式

    Java反射机制demo(七)—反射机制与工厂模式 工厂模式 简介 工厂模式是最常用的实例化对象模式. 工厂模式的主要作用就是使用工厂方法代替new操作. 为什么要使用工厂模式?直接new不好吗? 直 ...

  7. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  8. 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】

    方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...

  9. Java反射机制(三):调用对象的私有属性和方法

    一. 通过反射调用类中的方法 在正常情况下,得到类的对象后,我们就可以直接调用类中的方法了,如果要想调用的话,则肯定必须清楚地知道要调用的方法是什么,之后通过Class类中的getMethod方法,可 ...

随机推荐

  1. bzoj1485 有趣的数列

    传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1485 [题解] Catalan数,注意不能直接用逆元,需要分解质因数. # include ...

  2. 【leetcode 简单】 第九十八题 第三大的数

    给定一个非空数组,返回此数组中第三大的数.如果不存在,则返回数组中最大的数.要求算法时间复杂度必须是O(n). 示例 1: 输入: [3, 2, 1] 输出: 1 解释: 第三大的数是 1. 示例 2 ...

  3. Shell基础-通配符

    * - 通配符,代表任意字符 ? - 通配符,代表一个字符 # - 注释 | - 分隔两个管线命令的界定 ; - 连续性命令的界定 ~ - 用户的根目录 $ - 变量前需要加的变量值 ! - 逻辑运算 ...

  4. windows 下安装mysqlclient 包

    正常情况下是可以直接用 pip install mysqlclient 进行安装的.如果你的机器上安装的既有python3 又有python2.7 的话,建议使用python -m pip insta ...

  5. Qbot回归,已感染5.4万台计算机

    Qbot回归,已感染5.4万台计算机 近日,BAESystems的安全人员发表了一篇关于Qbot网络感知蠕虫回归的调查报告,指出已经感染了5.4万台计算机. FreeBuf百科 Qbot蠕虫,也叫Qa ...

  6. pip pytorch安装时出现的问题

    pytorch 的安装命令在官网就有,这里就不说了 执行安装命令 pip3 install http://download.pytorch.org/whl/cu80/torch-0.2.0.post3 ...

  7. CSS ... 文本溢出用省略号代替

    { overflow:hidden; text-overflow:ellipsis; white-space:nowrap } text-overflow 属性规定当文本溢出包含元素时发生的事情. c ...

  8. 【逆向知识】开发WinDBG扩展DLL

    如何开发WinDbg扩展DLL WinDbg扩展DLL是一组导出的回调函数,用于实现用户定义的命令.以便从内存转储中提取特定的信息.扩展dll由调试器引擎加载,可以在执行用户模式或内核模式调试时提供自 ...

  9. servlet Filter过滤javascript

    新建HttpServletRequestWrapper子类XssHttpServletRequestWrapper import javax.servlet.http.HttpServletReque ...

  10. 三、springboot热部署

    1.spring-boot-devtools 实现热部署 spring-boot-devtools 最重要的功能就是热部署.它会监听 classpath 下的文件变动,并且会立即重启应用. <d ...