• 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

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

  • 相关阅读:
    OAuth2认证
    Linux环境下conda虚拟环境的迁移
    Bash脚本学习 - 条件句、数组、for循环,函数
    【华为机试真题 JAVA】DNA序列-100
    部署gitlab,模拟开发流程。
    如何为Postgres数据库设置安全的访问控制和权限管理
    【slam十四讲第二版】【课本例题代码向】【第十讲~后端2】
    爬虫项目实战——爬取B站视频
    记一次前端CryptoJS AES解密
    C++ - Java 调用 C++ 动态库 <.dylib / .so> By CLion
  • 原文地址:https://blog.csdn.net/Apple_wolf/article/details/127562548