深入java虚拟机学习 -- 类的加载机制(四)

类加载的命名空间

每个类加载器都有自己的命名空间,命名空间由所有以此加载器为初始类加载器的类组成,不同命名空间的两个类是不可见的,但只要得到类所对应的Class对象的refrence(反射),还是可以访问另一个命名空间的类信息的。

同一个命名空间内的类是相互可见的,子加载器的命名空间包含所有父加载器的命名空间,也就是说由子加载器加载的类能看到父加载器加载的类。例如:系统类加载器加载的类能看到根类加载器加载的类(用户自定的类可以访问java.lang.*包下的信息),由父加载器加载的类不能看到子加载器加载的类。

如果两个加载器之间没有直接或者间接的父子关系,那么它们个字加载的类相互不可见。

创建用户自定义的类加载器

要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定的类的名字,返回对应的Class对象的引用。

protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }

我们可以按到ClassLoader里面的findClass方法的默认实现会抛出ClassNotFoundException异常,我们只需要在自定义的加载器里面重写,即可。

public class MyClassLoader extends ClassLoader
{

    private String name;//类加载器的名字
    private String path="";//加载类的默认路径
    private String fileType=".class"; //class文件的扩展名

    public MyClassLoader(String name){
        super();//让系统类加载器成为该类加载器的父加载器
        this.name=name;
    }
    public MyClassLoader(ClassLoader parent,String name){
        super(parent);//显示指定该类加载器的父加载器
        this.name=name;
    }

    @Override public String toString()
    {
        return this.name;
    }

    public String getPath()
    {
        return path;
    }

    public void setPath(String path)
    {
        this.path = path;
    }

    /**
     * 抽象类ClassLoader的findClass函数默认是抛出异常的。而前面我们知道,
     * loadClass在父加载器无法加载类的时候,就会调用我们自定义的类加载器中的findeClass函数,
     * 因此我们必须要在loadClass这个函数里面实现将一个指定类名称转换为Class对象.
     * @param name
     * @return
     */
    @Override protected Class<?> findClass(String name)
    {
        byte [] data=this.loadClassData(name);
        return this.defineClass(name,data,0,data.length);
    }

    private byte[] loadClassData(String name)
    {
        InputStream is=null;
        byte [] data=null;
        ByteArrayOutputStream baos=null;
        try
        {
            this.name=this.name.replace(".","\\");
            is=new FileInputStream(new File(path+name+fileType));
            baos=new ByteArrayOutputStream();
            int ch=0;
            while(-1!=(ch=is.read())){
                baos.write(ch);
            }
            data= baos.toByteArray();
        }
        catch(Exception e){
         e.printStackTrace();
        }
        finally
        {
            try
            {
                is.close();
                baos.close();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
        return data;
    }

    public static void main(String[] args) throws Exception
    {
        MyClassLoader loader1 = new MyClassLoader("loader1");//没有指定loader的父加载器,则默认的父加载器为系统类加载器
        loader1.setPath("G:\\myapp\\loader1\\");

        MyClassLoader loader2 = new MyClassLoader(loader1,"loader2");//指定loader2的父加载器为loader1,这里的loader1和loader2都为MyClassLoader的实例
        loader2.setPath("G:\\myapp\\loader2\\");

        MyClassLoader loader3 = new MyClassLoader(null,"loader3");//bootstrap类加载器
        loader3.setPath("G:\\myapp\\loader3\\");

        //test(loader1);
        test(loader2);
        test(loader3);
    }

    public static void test(ClassLoader loader) throws Exception
    {
        Class clazz=loader.loadClass("Sample");
        Object object=clazz.newInstance();
    }

 

开开心心编码,快快乐乐生活。
优秀的个人博客,低调大师

微信关注我们

原文链接:https://yq.aliyun.com/articles/672854

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
优质分享Android(本站安卓app)

优质分享Android(本站安卓app)

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

Eclipse(集成开发环境)

Eclipse(集成开发环境)

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。