getConstructor()和getDeclaredConstructor()区别

如何通过反射来创建对象?getConstructor()和getDeclaredConstructor()区别?

  1. 通过类对象调用newInstance()方法,适用于无参构造方法,只能调用空参的构造方法

    例如:String.class.newInstance()

public class Solution {

    public static void main(String[] args) throws Exception {

        Solution solution = Solution.class.newInstance();

        Solution solution2 = solution.getClass().newInstance();

        Class solutionClass = Class.forName("Solution");
        Solution solution3 = (Solution) solutionClass.newInstance();

        System.out.println(solution instanceof Solution); //true
        System.out.println(solution2 instanceof Solution); //true
        System.out.println(solution3 instanceof Solution); //true
    }
    
}
  1. 通过类对象的getConstructor()或getDeclaredConstructor()方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象,适用于无参和有参构造方法

    例如:String.class.getConstructor(String.class).newInstance(“Hello”);

public class Solution {

    private String str;
    private int num;

    public Solution() {

    }

    public Solution(String str, int num) {
        this.str = str;
        this.num = num;
    }

    public Solution(String str) {
        this.str = str;
    }

    public static void main(String[] args) throws Exception {

        Class[] classes = new Class[] { String.class, int.class };
        Solution solution = Solution.class.getConstructor(classes).newInstance("hello1", 10);
        System.out.println(solution.str); // hello1

        Solution solution2 = solution.getClass().getDeclaredConstructor(String.class).newInstance("hello2");
        System.out.println(solution2.str); // hello2

        Solution solution3 = (Solution) Class.forName("Solution").getConstructor().newInstance(); // 无参也可用getConstructor()
        System.out.println(solution3 instanceof Solution); // true
    }

}

getConstructor()和getDeclaredConstructor()区别:
getDeclaredConstructor(Class<?>… parameterTypes)
这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。
getDeclaredConstructors()的返回结果就没有参数类型的过滤了。
但是可以通过

//去除私有权限
 solution2.setAccessible(true);

再来看getConstructor(Class<?>… parameterTypes)
这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。
getConstructors()的返回结果同样也没有参数类型的过滤。

3.newInstance和new都可以创建对象,他们两有什么区别呢?

  • 类的加载方式不同

    在执行Class.forName(“a.class.Name”)时,JVM会在classapth中去找对应的类并加载,这时JVM会执行该类的静态代码段。在使用newInstance()方法的时候,必须保证这个类已经加载并且已经连接了,而这可以通过Class的静态方法forName()来完成的。
    使用关键字new创建一个类的时候,这个类可以没有被加载,一般也不需要该类在classpath中设定,但可能需要通过classlaoder来加载。

  • 所调用的构造方法不尽相同

    new关键字能调用任何构造方法。
    newInstance()只能调用无参构造方法。

  • 执行效率不同

    new关键字是强类型的,效率相对较高。
    newInstance()是弱类型的,效率相对较低。

  • 既然使用newInstance()构造对象的地方通过new关键字也可以创建对象,为什么又会使用newInstance()来创建对象呢?

    假设定义了一个接口Door,开始的时候是用木门的,定义为一个类WoodenDoor,在程序里就要这样写 Door door = new WoodenDoor() 。假设后来生活条件提高,换为自动门了,定义一个类AutoDoor,这时程序就要改写为 Door door = new AutoDoor() 。虽然只是改个标识符,如果这样的语句特别多,改动还是挺大的。于是出现了工厂模式,所有Door的实例都由DoorFactory提供,这时换一种门的时候,只需要把工厂的生产模式改一下,还是要改一点代码。
    而如果使用newInstance(),则可以在不改变代码的情况下,换为另外一种Door。具体方法是把Door的具体实现类的类名放到配置文件中,通过newInstance()生成实例。这样,改变另外一种Door的时候,只改配置文件就可以了。示例代码如下:
    String className = 从配置文件读取Door的具体实现类的类名;
    Door door = (Door) Class.forName(className).newInstance();
    再配合依赖注入的方法,就提高了软件的可伸缩性、可扩展性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值