首页 > 编程知识 正文

python类方法的使用,python类举例

时间:2023-05-06 20:39:47 阅读:32277 作者:241

类加载器负责将网络或磁盘上的class文件加载到内存中。 生成对应的java.lang.class对象。 当一个类加载到JVM中时,不会重新加载同一类。

怎么上同一个班呢? 在JAVA中,类由完全限定的类名(包名和类名)唯一标识,而在JVM中,类由完全限定的类名和类加载器唯一标识。 也就是说,如果在不同的类加载器中加载JAVA中的同一类,则生成的class对象将视为不同。

JVM启动后,将形成由三个类加载器组成的初始类加载器层次

1、启动类加载器BootstrapClassLoader:

是嵌入在用c语言编写的JVM内核中的装载器,主要装载JAVA_HOME/lib下的类库。 启动加载器不能直接用于APP应用程序。

2、扩展类加载器扩展类加载器:

加载器用JAVA编写,父类的加载器是Bootstrap,主要根据加载JAVA_HOME/lib/ext目录类库的sun.misc.launcher $ ext class loader 开发人员可以使用这些扩展类加载器。

已知由java系统属性java.ext.dirs指定的目录由ExtClassLoader加载程序加载。 如果程序未指定此系统属性(Djava.ext.dirs=sss/lib ),则加载器默认加载$JAVA_HOME/lib/ext

公共类测试

{

publicstaticvoidmain (字符串[ ] args ) {

system.out.println (system.getproperty (' Java.ext.dirs ' ) );

}

}

执行结果:

c :程序文件(x86 ) Javajdk1.6.0_43jrelibext; C:WindowsSunJavalibext

3、系统加载器app类加载器:

系统类加载器(也称为APP应用程序类加载器)将加载位于APP应用程序的classpath目录中的所有jar和class文件。 其父加载器是ext类加载器。

公共类测试

{

publicstaticvoidmain (字符串[ ] args ) {

system.out.println (class loader.getsystemclassloader ();

}

}

执行结果:

sun.misc.launcher $ app class loader @ addb f1

程序中的方法通过返回委托的系统类加载器,执行结果显示系统类加载器是在sun.misc.launcher $ app class loader中实现的。

上述三种加载器的层次关系如下。

注:类加载器的体系不是“继承”体系,而是代理体系。 大多数类加载器首先在自己的parent中查找类或资源。 如果找不到,在自己的本地找。 班级加载器的委托行动动机是为了防止同一班级多次加载。

可以通过程序验证:

publicstaticvoidmain (字符串[ ] args ) {

system.out.println (class loader.getsystemclassloader ().getParent ) );

}

执行结果:

sun.misc.launcher $ ext class loader @ 42e 816

从这里可以看到,应用程序类加载器的父加载器确实是ext类加载器。

我们上了一楼。 如果预期正确,则ext类加载器的父加载器应该是bootstrap类加载器

publicstaticvoidmain (字符串[ ] args ) {

system.out.println (class loader.getsystemclassloader ().getParent ) );

}

执行结果:

空值

这并不是说ExtClassLoader没有父加载器,而是因为Bootstrap ClassLoader是用c编写的。

UML类图:

现在,我们来解读源代码,看看这些类的继承关系

app类加载器和ext类加载器都是Lancher的内部类。

静态类扩展

Loader extends URLClassLoader

static class AppClassLoader extends URLClassLoader

public class URLClassLoader extends SecureClassLoader

public class SecureClassLoader extends ClassLoader

public abstract class ClassLoader

我们有这样一个结论,除了启动类加载器Bootstrap ClassLoader,其他的类加载器都是ClassLoader的子类。

我们来反编译看下rt.jar,在sun.misc.Launcher$AppClassLoader路径中,看下AppClassLoader的源码:

static class AppClassLoader extends URLClassLoader{

public static ClassLoader getAppClassLoader(ClassLoader paramClassLoader)

throws IOException{

String str = System.getProperty("java.class.path");

File[] arrayOfFile = (str == null) ? new File[0] : Launcher.access$200(str);

return ((AppClassLoader)AccessController.doPrivileged(new PrivilegedAction(str, arrayOfFile, paramClassLoader)

{

public Object run(){

URL[] arrayOfURL = (this.val$s == null) ? new URL[0] : Launcher.access$300(this.val$path);

return new Launcher.AppClassLoader(arrayOfURL, this.val$extcl);

}

}));

}

在第6行代码中可以看到,系统类加载器只能加载java.class.path路径下的class文件。我们通过程序看下java.class.path指定的路径

public class Test

{

public static void main(String[] args){

System.out.println(System.getProperty("java.class.path"));

}

}

执行结果:

如果是JAVA工程:

F:workSpacetestbin

如果是JAVAWEB工程:

F:workSpacestudyWebRootWEB-INFclasses

双亲委派模型

如果一个类加载器收到了一个类加载请求,它不会自己去尝试加载这个类,而是把这个请求转交给父类加载器去完成。每一个层次的类加载器都是如此。

因此所有的类加载请求都应该传递到最顶层的启动类加载器中,只有到父类加载器反馈自己无法完成这个加载请求(在它的搜索范围没有找到这个类)时,子类加载器才会尝试自己去加载。委派的好处就是避免有些类被重复加载。

双亲委派的实现比较简单,我们来看下源码:

protected synchronized Class> loadClass(String paramString, boolean paramBoolean)

throws ClassNotFoundException

{

//检查是否被加载过

Class localClass = findLoadedClass(paramString);

//如果没有加载,则调用父类加载器

if (localClass == null) {

try {

//父类加载器不为空

if (this.parent != null)

localClass = this.parent.loadClass(paramString, false);

else {

//父类加载器为空,则使用启动类加载器

localClass = findBootstrapClass0(paramString);

}

}

catch (ClassNotFoundException localClassNotFoundException)

{

//如果父类加载失败,则使用自己的findClass方法进行加载

localClass = findClass(paramString);

}

}

if (paramBoolean) {

resolveClass(localClass);

}

return localClass;

}

先检查是否已经被加载过,若没有加载则调用父类加载器的loadClass方法,若父类加载器不存在,则使用启动类加载器。如果父类加载器加载失败,则抛出异常之后看,再调用自己的findClass方法进行加载。

作者:冬瓜蔡

原文:http://www.cnblogs.com/dongguacai/p/5879931.html

始发于微信公众号: Java知音

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。