• jdk11使用反射创建实例对象


    1.目标

    通过反射创建实例化对象。

    2.问题

    1.如何创建
    2.是否传参数

    3.探索

    3.1 定义pojo类

    public class Person {
    
        private String name;
        private Integer age;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这里没有定义额外的构造函数,使用默认无参构造函数。

    3.2 测试类

    3.2.1 如何创建
    public class Test {
    
        public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class<Person> personClass = Person.class;
            Person constructors = personClass.newInstance();    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这时候有提示说newInstance()方法已经Deprecated。点进源码一看:

    /*
    Creates a new instance of the class represented by this Class object. The class is instantiated as if by a new expression with an empty argument list. The class is initialized if it has not already been initialized.
    Deprecated
    This method propagates any exception thrown by the nullary constructor, including a checked exception. Use of this method effectively bypasses the compile-time exception checking that would otherwise be performed by the compiler. The Constructor.newInstance method avoids this problem by wrapping any exception thrown by the constructor in a (checked) InvocationTargetException.
    The call
     clazz.newInstance()
    can be replaced by
     clazz.getDeclaredConstructor().newInstance()
    The latter sequence of calls is inferred to be able to throw the additional exception types InvocationTargetException and NoSuchMethodException. Both of these exception types are subclasses of ReflectiveOperationException.
    Returns:
    a newly allocated instance of the class represented by this object.
    Throws:
    IllegalAccessException – if the class or its nullary constructor is not accessible.
    InstantiationException – if this Class represents an abstract class, an interface, an array class, a primitive type, or void; or if the class has no nullary constructor; or if the instantiation fails for some other reason.
    ExceptionInInitializerError – if the initialization provoked by this method fails.
    SecurityException – If a security manager, s, is present and the caller's class loader is not the same as or an ancestor of the class loader for the current class and invocation of s.checkPackageAccess() denies access to the package of this class.
    */
    @CallerSensitive
        @Deprecated(since="9")
        public T newInstance() {
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    其中的原因:

    此方法传播由 nullary 构造函数引发的任何异常,包括已检查的异常。 使用此方法可以有效地绕过编译器执行的编译时异常检查。 Constructor.newInstance 方法通过将构造函数抛出的任何异常包装在(已检查)InvocationTargetException 中来避免此问题。

    使用clazz.getDeclaredConstructor().newInstance() 来替代clazz.newInstance() 即可。

    那么更改为:

    public class Test {
    
        public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class<Person> personClass = Person.class;
            Person constructors = personClass.getDeclaredConstructor().newInstance();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    3.2.2 是否传参数

    上一节测试了使用无参构造函数创建对象。那么使用有参构造函数可以吗?
    当然可以。

    public class Person {
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里添加了有参的构造函数,不会创建默认无参构造函数。

    public class Test {
    
        public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class<Person> personClass = Person.class;
            Person person = personClass.getDeclaredConstructor(String.class, int.class).newInstance("Yom", 34);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这样就可以调用有参构造函数创建对象了。

  • 相关阅读:
    进程以及线程
    【Spring】使用三方包进行数据源对象(数据库)管理
    pip修改位于用户目录下的缓存目录
    Linux驱动开发 问题随笔
    Springboot基于ElasticSearch全文搜索引擎策略实现
    我的第一个项目(十二) :分数和生命值的更新(后端增删查改的"改")
    IDEA04:动态加载配置文件
    C#通过TCP发送List<string>
    LeetCode 练习——剑指 Offer 66. 构建乘积数组
    高并发技巧-流量聚合和高并发写入处理技巧
  • 原文地址:https://blog.csdn.net/Apple_wolf/article/details/127562548