隐式方法:new 显式方法:1。java.lang.Class的forName方法2。java.lang.ClassLoader里的loadClass方法◆ 无法自行产生Class的实体,因为构造函数声明为private。◇ 只能通过Object的getClass方法,或者Class.forName("类名")获得。◆ Class类的实体在第一次载入内存时就建立了。以后在程序中产生Class代表的类的实体,其内部都会有个字段记录着这个Class类所在的位置。◇ 可以把每个Class类的实体当作是某个类(*.class)在内存中的代理。◆ 在Java中,每个类都是由某个类加载器(ClassLoader)来载入的,因此在Class类的实体中,由字段记录载入它的ClassLoader的实体。如果该字段是null,不代表它不是由类装载器所载入,而是代表这个类由引导式装载器(bootstrap loader)载入。但是这个装载器不是java编写的,所以没有实体。 图1注意:系统里同时存在多个ClassLoader实体。而且一个类装载器可以载入多个类★ 使用已有类装载器
注意:loadClass方法加载类时不会自动调用静态初始化块(static块),必须等到第一次实体化该类时,才会调用。这与forName时传入第二个参数为false的效果相同。下面是上述代码的另一种写法:
★ 自己建立类装载器来载入类URLClassLoader★ 类装载器的阶层体系Java程序运行流程:shur输入java ***.class,java.exe根据自己的搜索逻辑找到JRE,接着找到位于JRE中的jvm.dll(真正的java虚拟机)。最后载入这个动态链接库,激活java虚拟机。 虚拟机一旦激活,会先做一些初始化操作,如获取系统参数。 初始化完成后,产生第一个类装载器 Bootstrap Loader。然后做一些基本的初始化,然后它载入sun.misc命名空间底下的Launcher.java之中的ExtClassLoader,并设置其parent为null。然后Bootstrap Loader会继续载入sun.misc命名空间下的Launcher.java之中的AppClassLoader,并设置其parent为刚载入的ExtClassLoader实体。 最后由AppClassLoader负责载入***.class。 注意:上述三个类装载器搜索类的路径都是载入时读取的,分别是“sun.boot.class.path”、“java.ext.dirs”、“java.class.path”,而且在虚拟机中只保留一份。在系统运行过程中不可能动态改变,除非使用新的类装载器。★ 委托模型 类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入。如果Parent找不到,才由自己依照自己的搜索路径搜索类。
Powered by: BlogJava Copyright © 呆呆向前冲的blog