当前位置: 首页 > 软件教程 > Java类别载入器

Java类别载入器

2016年12月09日 13:39:57 访问量:16

 1 Java的动态特性

Java的动态特性有两种,一是隐式的;另一种是显示的。隐式的(implicit)方法就是当程式设计师用到new 这个Java 关键字时,会让类别载入器依需求载入您所需要的类别,这种方式使用了隐式的(implicit)方法。显式的方法,又分成两种方式,一种是藉由java.lang.Class 里的forName()方法,另一种则

是藉由java.lang.ClassLoader 里的loadClass()方法。您可以任意选用其中一种方法。

  2 隐式的动态特性

在执行java文件时,只有单独的变量声明是不会载入相应的类的,只有在用new生成实例时才载入

如示例所示:

public class Main

public static void main(String args[])

{

A a1 = new A() ;

B b1 ;

}

类A和B相同,如下:

public class A

{

public void print(“using A”);

}

编译后,可用java –verbose:class Main运行,察看输出结果。可以看到JVM只载入了A,而没有载入B.

另外,类的载入只在执行到new一个类时,才载入,如果没有执行到new语句,则不载入。

如://类Office

public class Office

{

public static void main(String[] args)

{

Word myword=null;

Excel myexcel=null;

if (args[0].equals("Word"))

{

myword = new Word();

myword.start();

}

if (args[0].equals("Excel"))

{

myexcel = new Excel();

myexcel.start();

}

}

}

//类Word和Excel基本相同,如下

public class Word

{

public void start()

{

System.out.println("using word");

}

}

在dos命令提示符下,输入java –verbose Office Excel可以看到JVM只载入Excel类,而不载入Word类。

3 显示的动态特性

3.1 java.lang.Class里的forName()方法

在上一个Office示例中,进行如下修改:

一 加入Assembly类

public interface Assembly

{

public void start();

}

二 让Word和Excel类实现该接口

public class Word implements Assembly

{

public void start()

{

System.out.println("using word");

}

}

三 Office 类如下所示

public class Office

{

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

{

java.lang.Class c = java.lang.Class.forName(args[0]);

Object o = c.newInstance();

Assembly a = (Assembly)o;

a.start();

}

}

  在命令提示符下输入java –verbose Office Word 输出入下:

通过上图你可以看到,interface 如同class 一般,会由编译器产生一个独立的类别档(.class),当类别载入器载入类别时,如果发现该类别继承了其他类别,或是实作了其他介面,就会先载入代表该介面的类别档,也会载入其父类别的类别档,如果父类别也有其父类别,也会一并优先载入。换句话说,类别载入器会依继承体系最上层的类别往下依序载入,直到所有的祖先类别都载入了,才轮到自己载入。

下面介绍一下 forName 函数, 如果您亲自搜寻Java 2 SDK 说明档内部对於Class 这个类别的说明,您可以发现其实有两个forName()方法,一个是只有一个参数的(就是之前程式之中所使用的):

public static Class forName(String className)

另外一个是需要三个参数的:

public static Class forName(String name, boolean initialize,ClassLoader loader)

这两个方法,最後都是连接到原生方法forName0(),其宣告如下:

private static native Class forName0(String name, boolean initialize, ClassLoader loader)

throws ClassNotFoundException;

只有一个参数的forName()方法,最後叫用的是:

forName0(className, true, ClassLoader.getCallerClassLoader());

而具有三个参数的forName()方法,最後叫用的是:

forName0(name, initialize, loader);

这里initialize参数指,在载入类之后是否进行初始化,对于该参数的作用可用如下示例察看:

类里的静态初始化块在类第一次被初始化时才被呼叫,且仅呼叫一次。在Word类里,加入静态初始化块

public class Word implements Assembly

{

static

{

System.out.println("word static initialization ");

}

public void start()

{

System.out.println("using word");

}

}

将类Office作如下改变:

public class Office

{

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

{

Office off= new Office();

System.out.println("类别准备载入");

java.lang.Class c = java.lang.Class.forName(args[0],true,off.getClass().getClassLoader());

System.out.println("类别准备实体化");

Object o = c.newInstance();

Object o2 = c.newInstance();

编辑:阿不力孜江吐尔地
评论区
发表评论

评论仅供会员表达个人看法,并不表明网校同意其观点或证实其描述
教育部 中国现代教育网 不良信息 垃圾信息 网警110
郑重声明:本站全部内容均由本单位发布,本单位拥有全部运营和管理权,任何非本单位用户禁止注册。本站为教育公益服务站点,禁止将本站内容用于一切商业用途;如有任何内容侵权问题请务必联系本站站长,我们基于国家相关法律规定严格履行【通知—删除】义务。本单位一级域名因备案流程等原因,当前临时借用网校二级域名访问,使用此二级域名与本单位官网权属关系及运营管理权无关。轮台县第十一小学 特此声明。
中华人民共和国电信经营许可证 ICP证 京ICP备13002626号-8 京公网安备11010502032087 轮台县第十一小学 版权所有
联系地址:新疆轮台县策达雅乡
北京网笑信息技术有限公司 仅提供技术支持 违法和不良信息举报中心