`
hm4123660
  • 浏览: 278033 次
  • 性别: Icon_minigender_1
  • 来自: 广州
博客专栏
Dea4ce76-f328-3ab2-b24a-fb268e1eeb75
数据结构
浏览量:68999
社区版块
存档分类
最新评论

java的类加载器ClassLoader

    博客分类:
  • Java
阅读更多

     类在执行之前会执行三个步骤:加载 ->   连接  -> 初始化

 

1.类的加载

     类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个Class对象,用来封装类在方法区的数据结构。可以把堆区的Class理解为方法区的一面镜子,对应方法区的类的数据结构,通过这面镜子实现类的调用。

 

加载.class文件的多种方式:

1.从本地系统中直接加载

2.通过网络下载.class文件

3.从zip,jar里加载.class文件

4.从专有的数据库中提取.class文件

5.将java源文件动态编译为.class文件

 

 类加载的最终结果是生成位于堆中的Class对象,Class对象封装了类在方法区内的数据结构,并且向java程序员提供了访问方法区内的数据结构的接口

 

查看源码得到Class对象只能由java虚拟机来创建,其构造函数私有化



 

 

2.连接

 

     1. 验证:确保被加载的类的正确性(主要防止恶心的class文件被加载)

 

     2. 准备:为类的静态变量分配内存,并将其初始化为默认值

 

     3. 解析:把类中的符合引用转换为直接引用

 

 

3.初始化

    为类的静态变量赋予正确的初始值

所有的java虚拟机实现必须在每一个类或接口被java程序“首次主动使用”时才初始化

 java对类的使用方式分为:主动使用,被动使用

主动使用有六种:(除这6种外,其他都是被动使用)

 

1。创建类的实例

 

2。访问某个类或接口的静态变量或对该静态变量赋值

 

3。调用类的静态方法

 

4。反射

 

5。初始化类的子类

 

6。java虚拟机启动时被标注位启动类的类

 

4.类加载器Classloader

 

类加载器类型

 

1.java虚拟机自带的类加载器:

 

-----根类加载器Bootstrap

    该类加载器没有父类加载器,它负责加载虚拟机的核心类库,如java.lang.String等,根类加载器用于在启动JVM时加载类,以使JVM能正常工作,因而它是用Native(c++)代码实现的,最早被创建出来,处于最底层。它并没有继承java.lang.ClassLoader类。

 

-----扩展类加载器Extension

    该类加载器的父类加载器是根类加载器。它从java.ext.dirs系统属性所指定的目录获取加载类库或从JDK的安装目录的jre\lib\ext子目录下加载类库。如果把jar放到这个目录下,也会自动用扩展类加载器加载。扩展类加载器是java类,是java.lang.ClassLoader类的子类

 

-----系统类加载器System

     也成为应用类加载器,它的父类加载器是扩展类加载器,它将加载CLASSPATH中配置的目录和jar文件,它是用户自定义类加载器的默认父类加载器,系统类加载器是java类,是java.lang.ClassLoader类的子类

 

 

2.用户自定义类加载器:是java.lang.ClassLoader的子类,可以定义类加载器

 

类加载器机制

    类加载器用来把类加载到java虚拟机中,类加载过程采用的是父亲委托机制,这种机制能很好的保证java平台的安全,因为在这种机制下用户定义的类加载器不可能加载应由父加载器加载的可靠类,如java.lang.String总是由根类加载器加载。在此委托机制中,除了java的根类加载器以外,其余的加载器都有且只有一个父加载器。

 

自定义类加载器

    用户自定义类加载器需要满足父委托机制,默认系统类加载器为其父加载器。要实现自定义加载器,只需要集成ClassLoader类,然后覆盖findClass(String name)方法,该方法根据参数指定加载类的名字,返回对应的Class对象的引用

 

自定义类加载器类: MyClassLoader

package com.longpo.classloader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {
	
	private String name; //类加载器的名字
	
	private String path="D:\\"; //加载类的路径
	
	private final String type=".class"; //class文件的扩展名
	
	public MyClassLoader(String name)
	{
		super();
		this.name=name;
	}

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

	//设置加载class的路径
	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}
	
	@Override
	public String toString() {
		return "MyClassLoader :" + name ;
	}

	
	//读取对应class文件的二进制数据---这里简单读取
	private byte[] loadClassData(String name)
	{
		//根据要加载的类名找到对应的文件
		name=name.replace(".", "\\");//com.longpo.test目录结构是\\
		
		File file=new File(path+name+type);
        //根据文件大小来创建字节数组  
        byte[]bytes=new byte[(int)file.length()] ;  

		try {
			InputStream is = new FileInputStream(file);
	        int len=is.read(bytes);//返回读取字节的长度
	        
	        is.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
 	
		return bytes;
	}
	
	//一定要重写该方法
	@Override
	public  Class<?> findClass(String name) throws ClassNotFoundException {
		//得到class文件的二进制数据
		byte[]data=loadClassData(name);
		
		return this.defineClass(name, data, 0,data.length);//返回class对象的引用
	}
	
	
}

 

定义一个测试加载类:Simple

package com.longpo.classloader;

public class Simple {

	public Simple( )
	{
		System.out.println("Simple的类加载器的名字是:"+this.getClass().getClassLoader());
	}
}

 

测试自定义加载类:Test

package com.longpo.classloader;

public class Test {

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

		//loader1的父加载器默认是系统加载器--上面还有系统加载器,扩展加载器,根加载器
		MyClassLoader loader1=new MyClassLoader("loader1");
		
		loader1.setPath("D:\\lib\\loader1\\");//loader1加载路径
		
		//loader2的父加载器为loader1--上面有loader1加载器,系统加载器,扩展加载器,根加载器
		MyClassLoader loader2=new MyClassLoader(loader1,"loader2");
		
		loader2.setPath("D:\\lib\\loader2\\");//loader2加载路径
		
		//loader3的父加载器为null,即根加载器--上面只有根加载器
		MyClassLoader loader3=new MyClassLoader(null,"loader3");
		loader3.setPath("D:\\lib\\loader3\\");//loader3加载路径
		
		test(loader2);
		test(loader3);
	}

	
	public static void test(ClassLoader loader)throws Exception{
		
		Class clazz=loader.loadClass("com.longpo.classloader.Simple");//loadClas会自动调用findClass方法
		
		Object object=clazz.newInstance();
		
	}
}

 

   此时把编译好的class文件发到对应加载器目录的文件夹里面,我用的是Eclipse,可在项目的目录的bin目录下找到.class文件
 

在Eclipse运行Test,得结果:



 

各个加载器的关系为



 

     使用loader2加载Simple时,根据父亲委托机制,会从根加载器开始尝试加载,一直往下加载,之道系统类加载器加载成功。使用loader3加载Simple,根据父亲委托机制,先由根加载器加载,加载失败后有loader3自己加载

  • 大小: 27.7 KB
  • 大小: 194 KB
  • 大小: 13.2 KB
  • 大小: 8.6 KB
  • 大小: 14.3 KB
  • 大小: 5.9 KB
7
1
分享到:
评论
1 楼 manxisuo 2015-06-09  
感谢博主,好文章。

相关推荐

    Java类加载器ClassLoader用法解析

    主要介绍了Java类加载器ClassLoader用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    深入java虚拟机(七)深入源码看java类加载器ClassLoader 1

    摘要视图订阅曹胜欢欢迎关注微信账号:java那些事:csh624366188.每天一篇java相关的文章登录 | 注册Java程序员从笨鸟到菜鸟(81)3054

    java应用程序类加载器,ClassLoader for java Application

    java应用程序类加载器(ClassLoader for java Application),类似exe4j, 方便启动java程序, 配置灵活,支持多平台选择性配置

    java类加载器实例

    类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...

    Java类加载器(ClassLoader)1

    如果户创建的JAR放在此录下,也会动由扩展类加载器加载.应程序类加载器(系统类加载器,Application ClassLoader)java语编写,由sun.

    JAVA ClassLoader 讲解 (类加载器)

    ClassLoader类加载器讲解,理解JAVA类加载机制

    java类加载器

    ClassLoader 三种类加载方式 Boostrap Extenxsion 以及Application ClassLoad分别适用的场景

    J2SE笔记讲解个人修订(1.1).docx

    14 JAVA类加载器CLASSLOADER 15 JAVA简单工厂模式 16 JAVA中的注解 17 JAVA 图形界面 18 JAVA多线程 19 JAVA 反射机制 20 JAVA克隆CLONE(复制) 21 JAVA 网络编程 22 JAVA 其他未归类 23 JNI概述

    ClassLoader类加载器

    ClassLoader的API使用和自定义

    掌握Java类加载器

    类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类文件的类。Java允许使用不同的类加载器,甚至自定义的类加载器。类加载器从源文件(通常是.class 或 .jar文件)...

    Java类加载机制与反射-PPT

    Java的类加载机制:加载,连接,初始化。JAVA类加载器: Bootstrap ClassLoader : 根类加载器, Extension ClassLoader: 扩展类加载器, System ClassLoader : 系统类加载器, Java反射

    自定义Java类加载器demo

    自定义Java类加载器demo,自定义了一个classLoader,重写了loadClass 和findClass,注意 loadClass打破了双亲委派机制,所有的类都要在自定义的class文件中找到,而findClass遵循了双亲委派机制

    Java类加载器原理

    自己根据一些文章总结的,不知道有没有漏洞,希望大家知道,谢谢

    ClassLoader类加载机制

    类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...

    classloader类加载器_基于java类的加载方式详解

    下面小编就为大家带来一篇classloader类加载器_基于java类的加载方式详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    java的ClassLoader类加载器机制

    jvm运行的过程中,需要载入类,而类的加载需要类加载器,本文章提供了java的类加载器的工作原理。可以使读者更加理解jvm的运行机制。

    深入java加载器源代码

    ClassLoader,,深入java加载器,,深入java加载器源代码

    java 类加载器 双亲委派 根加载器、扩展类加载器、系统类加载器

    类加载器分为根加载器(bootstrap classloader)、扩展类加载器(ext classloader)、系统类加载器(system classloader)、自定义类加载器(通常继承java.net.URLClassLoader,重写findClass()),它们的关系通常...

    类加载器文件

    JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。 SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。

    java类加载器1

    java.lang.ClassLoader 类介绍 java.lang.ClassLoader 类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字

Global site tag (gtag.js) - Google Analytics