Java对象创建过程
Java对象被创建有两种方式:第一种是通过new XX();第二种是Class.forName("XX").newInstance().我现在对这个流程的认识有些混乱.
要生成一个类的对象,必须有两样东西被加载到内存,一种是Class对象;另一种是类,然后类对象才会被创建.由于Java是动态加载(类的静态成员被引用,类才会别加载),所以类加载的时候相对于上面的两种方式分别是在:第一种:new XX(),因为构造器方法也是静态方法,这种方式会调用构造器方法,所以此时类会被加载;第二种:Class.forName()首先会检查类有无被加载,没有则加载类.至此,两种方式的类都被加载.
我的疑问是Class对象是何时被加载的,是和类一样吗?(我现在知道的关于Class对象的知识就是它是在.java文件被创建,被编译后产生了和类名字一样的.class文件.)是在类被加载之前还是之后,还有Class对象是怎么和类配合生成类对象的...希望大家能多多发表自己的见解.
------解决方案--------------------怎么说的有点乱七八糟的啊,加载类就是加载Class对象。
new XX();
Class.forName("XX").newInstance();
这两种效果一样,加载方式也一样,毫无区别,newInstance()实际上也是调用默认构造器方法的。
只是在用的场合不一样,前面一种用的很普遍。后面一种一般都是结合工厂模式应用的比较多。
------解决方案--------------------这两种方式效果是一样的,但是稍微有以下两点小区别:
区别1:Class.forName的方式能实现动态地载和创建Class 对象,而NEW指定生成某个类的对象
例:String str = 你定义的字符串
Class t = Class.forName(str);
t.newInstance();
区别2:JAVA的工厂模式中常使用Class.forName方式创建对象
------解决方案--------------------class Test{
}
还有一种方式,
Class<?> i=Test.class ;
i.newInstance();
不同之处:LZ列举上面2种都会伴随类的初始化,而这种不会伴随类的初始化。
------解决方案--------------------加载class二进制文件,生成该类对应的Class对象。
------解决方案--------------------ClassLoader读取class文件内容得到一个byte[],
然后就可以调用defineClass来在ClassLoader中生成Class
------解决方案--------------------http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html
------解决方案--------------------
------解决方案--------------------关键是 static initialization
class A {
//
static {
System.out.println("haha");
}
}
这个东西类似常量的初始化。
第一种调用方法,VM 启动的时候,会去找所有被 import 了的类,如果找到了,这段代码就会被调用。也就是一启动就会调用。
第二种方法,如果你一直没有 import 这个类,vm 一直等到 Class.forName("XX").newInstance() 才会调。如果 static initialization 里面写了很多代码,又不想在不需要的时候调用它们,就只有第二种方法来。
------解决方案--------------------编译:类名.java -> 类名.class
运行:类装载器 ->字节码验证器->....->通过JIT等生成存储在内存中的可执行代码...
首先是类装载器根据 类名.class 在文件中找到相应的 类名.class,然后加载该 类名.class,及将类名.class文件转化为java虚拟机中的类字节码。
Class.forName("XX") 返回值是一个Class类的实例对象,该Class对象封装了 XX.class的字节码数据,也就是生成存储在内存中的可执行代码。//Class类的作用
Class.forName("XX").newInstance() 返回的是XX.class类 中XX的一个实例对象。
举个例子:
public class classObjectTest{
public static void main(String args[])throws
ClassNotFoundException{
Class c;
classObjectTest cot=new classObjectTest();
c=Class.forName("classObjectTest");//相当于c=cot.getClass();
System.out.println(cot);
System.out.println(c);
System.out.println(c.getName());
}
}
结果:D:\>java classObjectTest
classObjectTest@de6ced
class classObjectTest
classObjectTest
也不知道对不对,有点晕了
------解决方案--------------------说明一下加载的过程:
public class LoaderTest{
public static void main(String args[])throws Class
NotFoundException{
Class c;
LoaderTest lt=new LoaderTest();
c=Class.forName("LoaderTest");
System.out.println(c);
System.out.println(c.getName());
System.out.println(c.getClassLoader());
System.out.println(c.getClassLoader().getParent());
System.out.println(c.getClassLoader().getParent().getParent());