类加载的命名空间

每个类加载器都有自己的命名空间,命名空间由所有以此加载器为初始类加载器的类组成,不同命名空间的两个类是不可见的,但只要得到类所对应的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();
}

深入java虚拟机学习 -- 类的加载机制(四)的更多相关文章

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

    昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...

  2. 深入java虚拟机学习 -- 类的加载机制

    当看到"类的加载机制",肯定很多人都在想我平时也不接触啊,工作中无非就是写代码,不会了可以百度,至于类,jvm是怎么加载的我一点也不需要关心.在我刚开始工作的时候也觉得这些底层的内 ...

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

    类的初始化时机 在上篇文章中讲到了类的六种主动使用方式,反射是其中的一种(Class.forName("com.jack.test")),这里需要注意一点:当调用ClasLoade ...

  4. Java基础_类的加载机制和反射

    类的使用分为三个步骤: 类的加载->类的连接->类的初始化 一.类的加载 当程序运行的时候,系统会首先把我们要使用的Java类加载到内存中.这里加载的是编译后的.class文件 每个类加载 ...

  5. 深入java虚拟机学习 -- 类的卸载

    类的生命周期 在开始本节之前让我们再来回顾下类的生命周期 没看过前6个过程的同学建议从头看下<深入java虚拟机学习 -- 类的加载机制>,这里就不再过多介绍了,着重说下类的卸载 类的卸载 ...

  6. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  7. JVM(1):Java 类的加载机制

    原文出处: 纯洁的微笑 java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang. ...

  8. Java虚拟机学习笔记——JVM垃圾回收机制

    Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...

  9. jvm系列 (五) ---类的加载机制

    类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...

随机推荐

  1. url路径去掉两个opencms

    采用刚刚的方法安装OpenCMS之后,站点url中会存在两个opencms,造成访问url路径过长,下面讲解一种去掉两个opencms的方法. 1.去掉第一个opencms 安装时采用ROOT安装,即 ...

  2. 可拖动布局之Gridster

    看过bootstrap可视化布局系统的人是不是都会对页面元素的拖拽有着很大的兴趣?下面呢,楼主就给大家讲两个楼主知道的拖拽小插件吧. 一.gridster 1.了解gridster 后续官网:http ...

  3. java常用类————Date类

    Date类在Java.util包中. 一.功能介绍:创建Date对象,获取时间,格式化输出的时间. 二.对象创建:1.使用Date类无参数的构造方法创建的对象可以获取本地时间.例如: Date now ...

  4. Ubuntu14.04+Nginx+MySql+PHP环境配置

    http://www.cnblogs.com/gophper/p/4793711.html

  5. Shell脚本的颜色样式及属性控制

    首先看一下格式 echo -e "\033[字背景颜色:文字颜色m字符串\033[0m" 举例 echo -e "\033[41;36m 字体 \033[0m" ...

  6. textarea只允许上下调节尺寸

    对于extarea,因为如果不做限制的话,它是可以自由调节尺寸的,对于这一点我相信用户是非常喜欢的,因为每个人都有自己认为合适的尺寸,但是对于前端来说就比较头疼了,因为随意调节宽高,就会破坏整体布局, ...

  7. vue项目中遇到的问题

    在 export defaul new Router({ )} 这个路由配置中一定要加mode : 'history' 否者就会在路由前面默认添加# 路由跳转的几种方式: 在VUE中使用less来编译 ...

  8. Linux PCI/PCI-E设备配置空间读取与修改

    Linux PCI/PCI-E设备配置空间读取与修改 1 前言 PCI和PCI Express,是计算机常使用的一种高速总线.操作系统中的PCI/PCI-E设备驱动以及操作系统内核,都需要访问PCI及 ...

  9. 深度学习菜鸟的信仰地︱Supervessel超能云服务器、深度学习环境全配置

    并非广告~实在是太良心了,所以费时间给他们点赞一下~ SuperVessel云平台是IBM中国研究院和中国系统与技术中心基于POWER架构和OpenStack技术共同构建的, 支持开发者远程开发的免费 ...

  10. GetWindowRect、GetClientRect、ScreenToClient与ClientToScreen

    GetWindowRect是取得窗口在屏幕坐标系下的RECT坐标(包括客户区和非客户区),这样可以得到窗口的大小和相对屏幕左上角(0,0)的位置. GetClientRect取得窗口客户区(不包括非客 ...