Java虚拟机-02:类与类加载器

 

 

640?wx_fmt=jpeg

图片来源:pixabay.com


640?wx_fmt=pngjava4all原创,欢迎关注640?wx_fmt=gif

摘要:本文主要介绍类加载器、类的唯一性、启动类加载器、拓展类加载器、应用程序类加载器。

 

640?wx_fmt=gif

 

内容目录:

 

1.类加载器

把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”的这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类,实现这个动作的代码模块称为“类加载器”;

 

2.类的唯一性

对于任意一个类,都需要由加载它的类加载器和这个类本身这两点一同确定其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。这句话也可以理解为:比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载他们的类的加载器不同,那么,这两个类必定不相等。

这个相等,包含代表类的Class对象的equals()方法、isAssignableFrom()方法、isInstance()方法的返回结果,也包括使用instanceof关键字做对象所属关系判定等情况。

 

在Java虚拟机中,从Java虚拟机的角度看,有两种不同的类加载器:

启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++语言实现的,是虚拟机自身的一部分;

这种分类是大方向上的,除了启动类加载器,其他的类加载器都是非启动类加载器,这些类加载器是Java语言实现的,独立于虚拟机外部,并且全都继承自抽象类java.lang.ClassLoader。

 

从Java开发人员的角度看,类加载器可以再细分一下,绝大部分Java程序都会使用到以下3种系统提供的类加载器:

 

3.启动类加载器 Bootstrap ClassLoader

这个类加载器负责将存放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数指定的路径中的,并且是虚拟机识别(这里说的识别,仅按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载)的类库加载到虚拟机内存中。启动类加载器无法被Java程序直接使用,用户在编写自定义类加载器时,如果需要把加载请求委派给引导类加载器,那直接使用null代替即可。

 

4.拓展类加载器 Extension ClassLoader

扩展类加载器是由sun.misc.Launcher$ExtClassLoader实现的,由Java语言实现的,是Launcher的静态内部类,它负责加载:

开发者可以直接使用扩展类加载器。

Launcher.class中的部分代码:

    public class Launcher {	
      static class ExtClassLoader extends URLClassLoader {	
        public static Launcher.ExtClassLoader getExtClassLoader() throws IOException {	
            final File[] var0 = getExtDirs();	
	
            try {	
                return (Launcher.ExtClassLoader)AccessController.doPrivileged(new PrivilegedExceptionAction<Launcher.ExtClassLoader>() {	
                    public Launcher.ExtClassLoader run() throws IOException {	
                        int var1 = var0.length;	
	
                        for(int var2 = 0; var2 < var1; ++var2) {	
                            MetaIndex.registerDirectory(var0[var2]);	
                        }	
	
                        return new Launcher.ExtClassLoader(var0);	
                    }	
                });	
            } catch (PrivilegedActionException var2) {	
                throw (IOException)var2.getException();	
            }	
        }	
       ......	
       }	
     }

5.应用程序类加载器 Application ClassLoader

应用程序类加载器是由sun.misc.Launcher$AppClassLoader实现的,由Java语言实现,由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,所以也称为系统类加载器,它负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用这个类加载器。

ClassLoader.class中的部分代码:

 
public abstract class ClassLoader {	
    private static java.lang.ClassLoader scl;	
    @CallerSensitive	
    public static java.lang.ClassLoader getSystemClassLoader() {	
        initSystemClassLoader();	
        if (scl == null) {	
            return null;	
        }	
        SecurityManager sm = System.getSecurityManager();	
        if (sm != null) {	
            checkClassLoaderPermission(scl, Reflection.getCallerClass());	
        }	
        return scl;	
    }	
    ......	
}

 

如果应用程序中没有自定义过自己的类加载器,一般情况下就是程序中默认的类加载器。

 

640?wx_fmt=jpeg

与其相忘江湖,不如点赞关注

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值