美文网首页
Constructor类

Constructor类

作者: OakesYa | 来源:发表于2020-05-18 20:18 被阅读0次

类图

之前我们用反射创建一个类的对象可以通过该Class.newInstance()方法,但是可以发现这个方法只能构造包含无参构造函数的类,如果不包含则会报NoSuchMethodException异常,那么这个时候就需要用到Constructor类了。我们先看看Constructor类的类关系图


类图

源码(精简版)

public final class Constructor<T> extends Executable {
    //用来存储ConstructorAccessor
    private Constructor<T>      root;
    //通过传入参数构造相对应的实例
    public T newInstance(Object ... initargs)
        throws InstantiationException, IllegalAccessException,
               IllegalArgumentException, InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, null, modifiers);
            }
        }
        if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            throw new IllegalArgumentException("Cannot reflectively create enum objects");
        ConstructorAccessor ca = constructorAccessor;   // read volatile
        if (ca == null) {
            ca = acquireConstructorAccessor();
        }
        @SuppressWarnings("unchecked")
        T inst = (T) ca.newInstance(initargs);
        return inst;
    }
    //获取ConstructorAccessor 
    private ConstructorAccessor acquireConstructorAccessor() {
        // First check to see if one has been created yet, and take it
        // if so.
        ConstructorAccessor tmp = null;
        if (root != null) tmp = root.getConstructorAccessor();
        if (tmp != null) {
            constructorAccessor = tmp;
        } else {
            // Otherwise fabricate one and propagate it up to the root
            tmp = reflectionFactory.newConstructorAccessor(this);
            setConstructorAccessor(tmp);
        }

        return tmp;
    }

    // 直接返回root里的ConstructorAccessor
    ConstructorAccessor getConstructorAccessor() {
        return constructorAccessor;
    }

    // 给root赋值
    void setConstructorAccessor(ConstructorAccessor accessor) {
        constructorAccessor = accessor;
        // Propagate up
        if (root != null) {
            root.setConstructorAccessor(accessor);
        }
    }
}

由于其他方法基本都是复写的父类等,所以这边就只看了newInstance方法,可以通过reflectionFactory.newConstructorAccessor(this);方法获取不同的ConstructorAccessor并调用newInstance创建一个实例

实例

public class EmployeeDto {
    private int age;
    private String name;

    EmployeeDto() {
        this.age = 0;
        this.name = "default";
    }

    EmployeeDto(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isOlder(int tmpAge) {
        return age > tmpAge;
    }

    @Override
    public String toString() {
        return "age:" + age + ",name:" + name;
    }
}

public class EmployeeConstructorTest {

    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("reflect.EmployeeDto");
            Constructor[] constructors = clazz.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                if (constructor.getParameterCount() == 2) {
                    constructor.setAccessible(true);
                    EmployeeDto employeeDto = (EmployeeDto) constructor.newInstance(1,"test");
                    System.out.println(employeeDto);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

EmployeeDto类有一个含参构造函数,然后main方法获取到该构造函数并newInstance创建一个实例并打印构建的对象,我们看看执行结果

Connected to the target VM, address: '127.0.0.1:65499', transport: 'socket'
age:1,name:test
Disconnected from the target VM, address: '127.0.0.1:65499', transport: 'socket'

执行没有问题

相关文章

  • Constructor类

    类图 之前我们用反射创建一个类的对象可以通过该Class.newInstance()方法,但是可以发现这个方法只能...

  • React中constructor及super

    constructor( ) 在React中constructor表示父类的构造方法,用来新建父类的this对象,...

  • 《Oracle Java SE编程指南》26-03:Constr

    内容导航: 前言 1、Constructor类 2、获得Constructor类实例 3、获取构造器信息 4、创建...

  • 理解React生命周期

    constructor React借用class类的constructor充当初始化钩子。在我们类扩展任何其他具有...

  • ES6面向对象

    类声明与构造函数 class 声明类constructor 构造函数 继承与超类

  • ES2015 Class

    传统写法: ES2015写法: 1、constructor方法 constructor方法是类的默认方法,通过ne...

  • super()方法详解

    基本概念: constructor(构造方法) constructor 是对es6类的默认方法,通过 new 命令...

  • Constructor、Method、Field

    Constructor Constructor表示类的构造函数,有一个原生的public方法: 该方法使用参数in...

  • JavaScript----类和继承

    类 构造函数Person中有一个构造函数constructor 调用构造函数的时候先调用constructor 继...

  • 反射

    通过 Class 对象分别获取Constructor类对象、Method类对象 & Field 类对象 通过 Co...

网友评论

      本文标题:Constructor类

      本文链接:https://www.haomeiwen.com/subject/xqhpohtx.html