new和newinstance()区别?

newInstance()是使用类加载机制,new关键字是创建一个新类。那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。

Java中工厂模式经常使用newInstance()方法来创建对象,因此从为什么要使用工厂模式上可以找到具体答案。 例如:真正起到消除耦合的,正是这个ExampleInterface 接口,而不是reflection

class c = Class.forName(“类的全限定名”);
ExampleInterface factory = (ExampleInterface)c.newInstance();

其中ExampleInterface是Example的接口,可以写成如下形式:

String className = "类的全限定名";
class c = Class.forName(className);
ExampleInterface  factory = (ExampleInterface)c.newInstance();

进一步可以写成如下形式:

String className = readfromXMlConfig;//从xml 配置文件中获得字符串
class c = Class.forName(className);
ExampleInterface factory = (ExampleInterface)c.newInstance();

上面代码已经不存在Example的类名称,它的优点是,无论Example类怎么变化,上述代码不变,甚至可以更换Example的兄弟类Example2 , Example3 , Example4……,只要他们继承ExampleInterface就可以。

从jvm的角度看,我们使用new的时候,这个要new的类可以没有加载;但是使用newInstance时候,就必须保证:
1、这个类已经加载;
2、这个类已经连接了。

上面两个步骤的正是class的静态方法forName()方法,这个静态方法调用了启动类加载器(就是加载java API的那个加载器)。

有了上面jvm上的理解,那么我们可以这样说,newInstance实际上是把new这个方式分解为两步,即,首先调用class的加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了我们降耦的手段。

最后用最简单的描述来区分new关键字和newInstance()方法的区别:

newInstance(): 弱类型。低效率。是实现IOC、反射、面对接口编程和依赖倒置等技术方法的必然选择!
new: 强类型。相对高效。能调用任何public构造。new只能实现具体类的实例化,不适合于接口编程。

1、类的加载方式不同

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

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

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

3、执行效率不同

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

两种方式的区别:
Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数,要求被调用的构造函数是可见的,也即必须是public类型的;
Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数,在特定的情况下,可以调用私有的构造函数。

package com.zs.newclass;

import java.lang.reflect.Constructor;

/**
 * @author zhaoshuai06 <zhaoshuai06@kuaishou.com>
 * Created on 2021-06-17
 */
public class A {
    private A() {
        System.out.println("A is private construct is called.");
    }
    private A(int a, int b) {
        System.out.println("a: "+ a + ",b: " + b);
    }
}
class B {
    public static void main(String[] args) {
        B b = new B();
        System.out.println(" 通过class.NewInstance() 调用私有构造方法:");
        b.newInstanceByClassNewInstance();

        System.out.println(" Constructor.NewInstance() 调用私有构造方法:");
        b.newInstanceByConstructorNewInstance();

    }
    private void newInstanceByClassNewInstance() {
        try {
            A a = (A) Class.forName("A").newInstance();
        }catch (Exception e) {
            System.out.println(" 通过class.NewInstance() 调用私有构造方法:(失败)");
        }
    }

    private void newInstanceByConstructorNewInstance() {
        try{
            Class<?> c = Class.forName("com.zs.newclass.A");
            // 无参数的私有构造器
            Constructor<?> c0 = c.getDeclaredConstructor();
            c0.setAccessible(true);
            A a0 = (A) c0.newInstance();
            // 有参数的私有构造器
            Constructor<?> c1 = c.getDeclaredConstructor(new Class[] {int.class, int.class});
            c1.setAccessible(true);
            A a1 = (A) c1.newInstance(new Object[] {5, 6});
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 通过class.NewInstance() 调用私有构造方法:
 通过class.NewInstance() 调用私有构造方法:(失败)
 Constructor.NewInstance() 调用私有构造方法:
A is private construct is called.
a: 5,b: 6
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值