当我们用new创建对象时,JVM做了以下事情:
1、若对应类的class文件未加载,加载对应的class文件,进行类的链接、初始化操作。
2、根据方法区中的类信息向堆内存申请空间。
3、调用构造函数。
由于运用new创建实例比较熟悉,就不给出实例证明了。
利用newInstance创建对象时,是默认JVM已经完成了对应类的加载、链接工作的,下面给出个实例:
package pkgtry;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class A
{
int y;
public A(int x)
{
y=x;
}
static
{
System.out.println("加载类A");
}
}
public class Try {
public static void main(String[] args) {
try
{
Class aclass=ClassLoader.getSystemClassLoader().loadClass("pkgtry.A");//只是加载类
Constructor c=aclass.getConstructor(int.class);//此时完成验证、准备、解析工作
A a=(A)c.newInstance(1);//完成初始化工作,接着调用构造函数,此时可能发生解析
System.out.println(a.y);
}
catch(ClassNotFoundException x)
{
System.out.println("无法加载对应类");
}
catch (NoSuchMethodException x)
{
System.out.println("类中没有对应方法");
}
catch(InstantiationException x)
{
System.out.println("为抽象类或接口");
}
catch(IllegalAccessException x)
{
System.out.println("构造方法非public修饰");
}
catch(InvocationTargetException x)
{
System.out.println("方法抛出了异常");
}
}
}
运行结果如下
从上面可以看出,运用new创建实例对象类可以未加载,而调用newinstance时类必须完成加载和链接操作。
运用new创建实例对象,实例对象所对应的类必须被导入或是我们自定义,而newinstance使用的是反射机制,可以在运行时再来检测类是否存在,并且newinstance只能调用public修饰的构造函数,new可以调用包中的非public构造函数,关于反射机制,可以查看我的另一篇博客:点击打开链接,另外,网上有种说法说newinstance只能调用无参构造,从上面例子中可以看出并不是这样。