jdk11使用反射创建实例对象

1.目标

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

2.问题

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

3.探索

3.1 定义pojo类

public class Person {
    
    

    private String name;
    private Integer age;
}

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

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();    }
}

这时候有提示说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() {
    
    
    }

其中的原因:

此方法传播由 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();
    }
}
3.2.2 是否传参数

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

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

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

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

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);
    }
}

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

猜你喜欢

转载自blog.csdn.net/Apple_wolf/article/details/127562548