`
beyondqinghua
  • 浏览: 41458 次
  • 性别: Icon_minigender_1
  • 来自: 南昌
社区版块
存档分类
最新评论

认识java的类加载器(一)

    博客分类:
  • JSE
阅读更多

1、认识类装载器:

类装入组件是 JAVA 虚拟机的基础,其是一个重要的、但又常常被我们忽略的 JAVA 运行时系统组件。它是负责在运行时查找和装入类文件的类,因此创建自己的 ClassLoader 可以非常方便的定制 JVM

JAVA编译的程序是一种特殊的、独立于平台的格式,并非依赖于它们所运行的平台。JAVA编译的类文件在运行时并非立即全部都装入内存,而是根据程序需要装入内存,有点类似我们操作系统的虚拟存储管理,根据。ClassLoader JVM 中将类装入内存的那部分。

JAVA的类加载器本身就是用 JAVA编写的,这意味着创建您自己的 ClassLoader 非常容易,不必了解 JVM的低层细节。

那么为什么要创建自己的类加载器呢,主要是由于JAVA默认的类加载器只能加载本地的类文件,这与JAVA的网络特性非常的不合,因此,有必要根据需要修改JAVA的类加载器方便的从网络加载类文件。

有许多其它方式可以获取类文件。除了简单地从本地或网络装入文件以外,可以使用定制的 ClassLoader 完成以下任务:

n        在执行非置信代码之前,自动验证数字签名

n        使用用户提供的密码透明地解密代码

n        动态地创建符合用户特定需要的定制化构建类

任何您认为可以生成 JAVA 字节码的内容都可以集成到应用程序中。

每个 Class 对象都包含一个对定义它的 ClassLoader 引用

数组类的 Class 对象不是由类加载器创建的,而是由 Java 运行时根据需要自动创建。数组类的类加载器由 Class.getClassLoader() 返回,该加载器与其元素类型的类加载器是相同的;如果该元素类型是基本类型,则该数组类没有类加载器。

2、如何定制ClassLoader

我相信编写过Applet程序的朋友都知道,通过Http协议我们可以从远程服务器上下载JAVA字节代码进行加载运行,这都归功与JAVA的自定义类加载器,Applet查看器内置了一个类加载器,它不是在本地加载类文件,而是通过Http协议从网络中加载。同时这个加载器还可以做其它事情,通过JAVA的沙箱来限制Applet的安全范围,并且不干扰其他的Applet程序。

类加载器ClassLoader是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。

ClassLoader 类使用委托模型来搜索类和资源。每个 ClassLoader 实例都有一个相关的父类加载器。需要查找类或资源时,ClassLoader 实例会在试图亲自查找类或资源之前,将搜索类或资源的任务委托给其父类加载器。虚拟机的内置类加载器(称为 "bootstrap class loader")本身没有父类加载器,但是可以将它用作 ClassLoader 实例的父类加载器。

实例代码:

 

import java.io.*;

class NetworkClassLoader extends ClassLoader {
    
    private String host;
    private int port;
    
    public static void main(String[] args)throws Exception{
		
		 ClassLoader loader = new NetworkClassLoader("127.0.0.1", 4444);
         Object pig = loader.loadClass("Pig.class").newInstance();
	}
    
    public NetworkClassLoader(){
    }
    
    public NetworkClassLoader(String host,int port){
    	this.host = host;
    	this.port = port;
    }
    
    //类加载器
    public Class loadClass( String name, boolean resolve ) throws ClassNotFoundException{
    	// 目标Class
        Class clas = null;

        // 看是否已经加载该类
        clas = findLoadedClass( name );
        
        
        if(clas == null){
        	clas = findClass(name);
        }
        
        //如果class对象不存在则在系统中查找
        if (clas==null) {
          clas = findSystemClass( name );
        }
        
        if(clas == null){
        	
        	throw new ClassNotFoundException("该类不存在1");
        }
        
        //是否需要分析该类
        if (resolve && clas != null)
            resolveClass( clas );
        return clas;
     }
    
    //构造该类的Class对象
    public Class findClass(String name){
    	try{
            byte[] b = loadClassData(name);
            if(b == null){
            	return null;
            }
            System.out.println("my findClass method");
            
            return defineClass("Pig", b, 0, b.length);
            
        }catch(IOException e){
        	System.out.print(e.getMessage());
        }
        return null;
    }
    
    //从网络加载加载类的二进制代码,此处我们使用本地文件
    private byte[] loadClassData(String name)throws IOException{
        
        //读取类文件
        File file = new File(name);
        if(!file.exists()){
        	return null;
        }
        FileInputStream input = new FileInputStream(file);
        long length = file.length();
        byte[] bt = new byte[(int)length];
        
        int rl = input.read(bt);
        
        if(rl != length){
        	throw new IOException("不能读取所有内容");
        }
        input.close();
        
        return bt;
    }
}

 

Class loadClass( String name, boolean resolve )方法ClassLoader 的入口点。

使用指定的二进制名称来加载类。此方法的默认实现将按以下顺序搜索类:

l        调用 findLoadedClass(String) 来检查是否已经加载类。

l        在父类加载器上调用 loadClass 方法。如果父类加载器为 null,则使用虚拟机的内置类加载器。

l        调用 findClass(String) 方法查找类。

l        如果使用上述步骤找到类,并且 resolve 标志为真,则此方法将在得到的 Class 对象上调用 resolveClass(Class) 方法。

鼓励用 ClassLoader 的子类重写 findClass(String),而不是使用此方法。

finalClass<?>defineClass(String name,byte[] b,int off,int len)方法 ClassLoader 的主要功能部件。该方法接受由编译后的字节的数组并把它转换成 Class对象。原始数组包含如从文件系统或网络装入的数据。

defineClass 管理 JVM 的许多复杂、神秘和倚赖于实现的方面 -- 它把字节码分析成运行时数据结构、校验有效性等等,类似编译器的自动机。而且你没有办法重写这个方法,正如你看到的,他是final类型。

final Class<?> findSystemClass(String name)方法从本地classpath中装入文件。它在本地文件系统中寻找类文件,如果存在,就使用 defineClass 将原始字节转换成 Class 对象,以将该文件转换成类。当运行 Java 应用程序时,这是 JVM的缺省类文件装载机制。

final Class<?> findLoadedClass(String name)方法用来判断类加载器是否已经加载了该类,避免不必要的资源浪费,建议首先调用该方法。

分享到:
评论

相关推荐

    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概述

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    15.2.1 类加载器层级架构 515 15.2.2 建立classloader实例 518 15.3 重点复习 520 15.4 课后练习 521 chapter16 自定义泛型、枚举与标注 523 16.1 自定义泛型 524 16.1.1 定义泛型方法 524 16.1.2 ...

    大白话带你认识JVM.pdf

    如果 JVM 想要执行这个 .class 文件,我们需要将其装进一个 类加载器 中,它就像一个搬运工一样,会把所有的 .class 文件全部搬进JVM里面来。 ② 方法区 方法区 是用于存放类似于元数据信息方面的数据的,比如类...

    JAVA面试题最全集

    一个“.java”原文件中是否可以包括多个类(不是内部类)? 53.掌握内部类和接口的概念 54.StringTokenizer类的使用 55.数据结构,如何遍历List中的元素? 如果要按照键值保存或者访问数据,使用什么数据结构? ...

    很入理解JVM体系

    部分章节如下,内容在...1、类加载器 2、执行引擎 3、运行时数据区 4、本地库接口 2.3、JVM内存参数调整及监控 1、JVM之内存调整 2、JVM监控工具之Jconsole 3、JVM监控工具之JProfile 加群:113035529 共同交流学习

    java实验报告.doc

    淮海工学院计算机工程学院 实验报告书 课程名:《面向对象程序设计》 实验名称: java程序设计基础 班 级: 学 号: 姓 名: 一、目的与要求 1、熟悉Java开发工具 认识J2SE开发环境,对TextPad、JCreator、NetBeans...

    Java常见面试问题整理.docx

    在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/O 方式,它可以使用native 函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer 对象作为这块...

    java面试题

    Struts2只是起到一个数据接收和转接的功能,就是Controller控制器,而传来数据的页面叫view显示层,Struts2将数据提交给进行处理的类叫Model模型层,专门进行数据处理和数据库的连接。 heap和stack有什么区别? 答:...

    java8rt.jar源码-jvm:jvm入门jvm面试题

    谈谈JVM中,类加载器你的认识? rt-jar ext application 1、JVM的位置 2、JVM的体系结构 大多数将内存分配为Method Area(方法区)、Heap(堆)、Program Counter Register(程序计数器)、JAVA Method Stack(JAVA方法栈)...

    Java面试题大全带答案,2023年最新持续更新.txt 免费下载

    说一下Java对象的创建过程 ... 谈谈JVM中,对类加载器的认识 你对线程优先级的理解是什么? 构造器(constructor)是否可被重写(override) JVM 年轻代到年老代的晋升过程的判断条件是什么呢?

    Java学习指南(Swing入门篇)

    布局管理器的使用- 自定义布局- 图片的加载及使用- 对话框,及自定义对话框- 菜单和工具栏- 自定义绘图- JList 列表框的用法,以及单元格的自定义显示- JTable 表格的用法,以及单元格的自定义显示- 一个基于 JTable...

    c#学习笔记.txt

    readonly声明一个字段,该字段只能赋值为该声明的一部分或者在同一类的构造函数中。 sealed指定类不能被继承。 static声明属于类型本身而不是属于特定对象的成员。 unsafe声明不安全的上下文。 virtual在派生类中...

    Spring.3.x企业应用开发实战(完整版).part2

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...

    Spring3.x企业应用开发实战(完整版) part1

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第二阶段49讲、自定义类加载器ClassLoader顺便问候了一下世界.mp4 │ 高并发编程第二阶段50讲、ClassLoader父委托机制详细介绍.mp4 │ 高并发编程第二阶段51讲、加密解密类加载实战演示.mp4 │ 高...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段49讲、自定义类加载器ClassLoader顺便问候了一下世界.mp4 │ 高并发编程第二阶段50讲、ClassLoader父委托机制详细介绍.mp4 │ 高并发编程第二阶段51讲、加密解密类加载实战演示.mp4 │ 高...

    PHP培训教程之AJAX技术.docx

    通过HTTPRequest,一个web页面可以一个请求到web器并且接受web器返回的信息(不用重新加载页面),展示给用户的还通一个页面,用户感觉页面刷新,也看不到到Javascript后台进行的请求和接受响应。 7、AJAX请求总共有...

    C#微软培训资料

    第一章第一章 第一章 .NET 编 编 编程语言 程语言编程语言 程语言 C#.4 1.1 Microsoft.NET——一场新的革命.4 1.2 .NET 与 C#.6 1.3 C#语言的特点.8 1.4 小 结 .11 第二章 运行环境 全面了解.NET....

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    这些都预示着我们进入了一个新的互联网阶段web 2.0,它是相对web 1.0的新的一类互联网应用的总称,是一次从核心内容到外部应用的革命[10]。这个阶段发展迅速,互联网应用趋于多样化,其中变化最大的是由web 1.0网站...

Global site tag (gtag.js) - Google Analytics