`
lxy2330
  • 浏览: 469319 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java类装载机制

    博客分类:
  • java
阅读更多

当我们在命令行输入java Xxx(某个类)时候,java内部会做些什么动作呢?

Java Xxx
流程如下:
1.         找到JRE;
2.         找到JVM.dll;
3.         启动JVM,并进行初始化;
4.         产生Bootstrap Loader;
5.         载入ExtClassLoader;(Ext – Extended)
6.         载入AppClassLoader;
7.         加载Xxx类。
Bootstrap Loader、ExtClassLoader和AppClassLoader构成了Java的“类加载器继承体系--class loader hierarchy”,其中Bootstrap Loader是由C++编写的,其他两个是由Java写的。之所以成为“继承体系”是因为这三个loader之间是有联系的。Bootstrap Loader负责加载ExtClassLoader,后者ExtClassLoader就将其parent置为Bootstrap Loader。AppClassLoader较为特殊,虽然由Bootstrap载入,但是其parent却置为ExtClassLoader。其原因是为了实现“委托模型”也就是下面所说的“双亲委派模型”简述“委托模型”就是当类加载器有加载类的需求时,会先请求其parent使用其搜索路径帮助加载,如果其parent找不到,才使用自己的搜索路径进行加载。如上述所说当ExtClassLoader想载入AppClassLoader类时它首先请求其parent “Bootstrap Loader”帮忙,Bootstrap Loader将AppClassLoader载入后,由于这个载入是ExtClassLoader请求的,所以AppClassLoader的parent还是置为ExtClassLoader而不是Bootstrap Loader。
 
类的加载流程
类加载的时候遵循一个原则:“类加载器会依类的继承体系从上至下依次加载”。举个例子:“如果C继承了B并实现了接口I,而B有继承自A”,则类加载器在加载C时,加载的次序会是AàBàIàC,(注:interface会如同class一样被Java编译器编译为独立的.class文件)

类装载器:java虚拟机使用每一个类的第一件事情就是将该类的字节码装载进来,装载类字节码的功能是有类装载器完成的,类装载器负责根据一个类的名称来定位和生成类的字节码数据后返回给java虚拟机。最常见的类加载器是将要加载的类名转换成一个.class文件名,然后从文件系统中找到该文件并读取其中的内容,这种类装载器也不是直接将.class文件中的内容原封不动地返回给java虚拟机,它需要将.class文件中的内容转换成Java虚拟机使用的类字节码,譬如,Java程序中的字符串编译成.class文件后是以UTF-8编码存在的,而装载进java
虚拟机后要被转换成Unicode编码。类装载器本身也是一个Java类,允许开发人员自己编写自己的类装载器,以便通过其他各种特殊方式来产生类字节码。我们可以对一些.class文件进行加密处理来防止反编译,但需要使用特殊的类装载器从已被加密处理的.class文件中还原出正常的字节码即可。不管类装载器采用什么方式,只要能够在内存制造出Java虚拟机调用类字节码即可。所以,把类装载器描述为类字节码制造器更容易让人理解。
当一个类被加载后,Java虚拟机将其编译为可执行代码存储在内存中,并将索引信息存储进一个HashTable中,其索引关键字在HashTable中查找相应的信息,如果该代码已经存在,虚拟机直接从内存里调用该可执行代码,反之则调用类装载器并进行加载和编译。
    一个Java类用来描述现实中的事物,Java程序也是一种事物,它可以用一个Java类描述,这个特殊的类名就叫Class。Class类用于描述Java程序语言中使用的一个类的有关信息。可以认为,类装载器装载某个类的字节码的过程实际上就是在创建Class类的一个实例对象,这个Class类的实例对象封装的内容正好是当前加载的类的字节码数据,也就是Java虚拟机对当前加载类编译后存储在内存中的可执行代码!可以采用下面三种方式获得:
    1。类名.class ,例如。System.class
    2。对象.getClass(),例如。new Date().getClass()
    3。Class.forName("类名"),例如,Class.forName("java.util.Date");
    类装载器本身也是一个java类,java类库中提供了一个java.lang.ClassLoader来作为类装载器的基类,java虚拟机和程序都调用ClassLoader的子类。Class类中定义了一个getClassLoader方法,用于返回它所描述的类的类装载器对象,这个返回对象的类型就是ClassLoader.

 双亲委派模型:

在此模型下,当一个装载器被请求装载某个类时,它首先委托自己的parent去装载,若parent能装载,则返回这个类所对应的Class对象,若parent不能装载,则由parent的请求者去装载。

 下面是类装载器使用示例:       

package cn.itcast;
import java.io.*;

public class MyClassLoader extends ClassLoader
{
 private String path = null;  
 public MyClassLoader(String path)
 {
  //错误检查省略
  this.path = path;
 }
 
 
 protected  class findClass(String name)
 {
  
try
  {
   File f = new File(path,name.substring(name.lastIndexOf('.')+1) + ".class");
   FileInputStream fis = new FileInputStream(f);
   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   cypher(fis,bos);
   byte [] buf = bos.toByteArray();
   fis.close();
   bos.close();
   return defineClass(name,buf,0,buf.length);
  }catch(Exception e)
  {
   e.printStrackTrace() ;
  }
  return null;
 }
 
 public static void cypher(InputStream ips , OutputStream ops)
 {
  
try
  {
   int b = 0;
   while((b=ips.read()) != -1)
   {
    ops.write(((byte)b) ^ 0xff);
   }
  }catch(Exception e){}
 }
 
 public static void main(String [] args)
throws Exception
 {
   if(!args[0].endsWith("class"))
   {
    System.out.println(
     MyClassLoader.class.getClassLoader().getClass().getName());
    ClassLoader loader = new MyClassLoader(args[1]);
    ClassLoader ld = loader.getParent();
    while(ld != null)
    {
     System.out.println("     " + ld.getClass().getName());
     ld = ld.getParent();
    }
    Class cls = loader.loadClass(args[0]);
    System.out.println(cls.getClassLoader().getClass().getName());
    java.util.Date d = (java.util.Date)cls.newInstance();
    System.out.println(d.toString());
    return;
   }
  
   FileInputStream fis = new FileInputStream(args[0]);  
   File f = new File(args[1], new File(args[0]).getName());//不用检查目录最后是否有目录分割符
   FileOutputStream fos = new FileOutputStream(f);  
   cypher(fis,fos);
   fis.close();
   fos.close();  
 }
 
}

分享到:
评论

相关推荐

    Java虚拟机类装载机制

    Java虚拟机类装载机制是Java运行环境中的核心组成部分,它负责将类的字节码从磁盘、网络等不同来源加载到JVM中,并进行一系列处理以使类能够被正确地使用。类装载机制的目的是为了实现代码的动态加载和运行时的灵活...

    JAVA虚拟机的类装载机制的原理分析与应用研究.pdf

    Java虚拟机(JVM)是Java程序运行的核心,它的类装载机制是理解Java应用程序如何启动、运行和管理的关键。本文将深入探讨Java虚拟机的类装载机制,包括其原理、工作流程以及在实际开发中的应用。 类装载机制是Java...

    Java虚拟机类装载:原理、实现与应用

    Java虚拟机类装载机制是Java运行环境的核心技术之一,它允许程序在运行时动态加载和使用类,极大地增强了软件的灵活性和可扩展性。本文主要探讨了类装载的原理、实现方式及其在实际应用中的作用。 首先,类装载的...

    利用类装载器动态加载类并启动类

    此方法不仅加深了我们对于Java类装载机制的理解,同时也提供了一种实用的数据保护手段。 #### 位移加密算法 位移加密算法是一种简单但有效的加密方式,主要通过改变字节的二进制位位置来实现加密和解密功能。 ####...

    Java虚拟机类装载的原理及实现

    ### Java虚拟机类装载的原理及实现 #### 引言 Java虚拟机(JVM)作为执行Java程序的核心,承担着解释执行字节码的...通过深入了解类装载的过程和机制,开发者可以更好地利用这一特性来优化和增强Java应用程序的功能。

    [浅析J2EE应用服务器的JAVA类装载器]python回朔异常的模块.docx

    Java类装载器机制是Java语言灵活性的关键组成部分,尤其在J2EE应用服务器中扮演着重要角色。理解这一机制有助于开发者更好地部署和管理应用程序,解决可能出现的部署问题。 Java类装载器是Java虚拟机(JVM)的一...

    Java虚拟机类装载.doc

    Java虚拟机类装载 Java虚拟机(JVM)的类装载是指将包含在类文件中的字节码装载到JVM中...了解了JVM中的类装载机制和ClassLoader的工作原理,可以更好地理解Java虚拟机的工作机制,并更好地使用Java语言开发应用程序。

    Java类装载过程_.docx

    Java 类装载过程是Java虚拟机(JVM)运行的核心机制之一,主要涉及到类从加载到初始化的完整生命周期。这一过程确保了程序的正确运行,并在安全性方面起到关键作用。以下是详细的解释: 1)装载(Loading): 在这...

    Java卡的可信代码装载机制设计.pdf

    "Java卡的可信代码装载机制设计" 本文将详细介绍Java卡的可信代码装载机制设计,以满足可信计算平台(TCP)需求。该设计基于Java卡技术,采用代码签名技术作为主要手段,以卡内的安全域(Security Domain)作为各个...

    Java虚拟机类装载:原理、实现与应用.doc

    Java虚拟机(JVM)的类装载机制是Java运行时环境的核心组成部分,它负责将类文件中的字节码加载到JVM中,使类成为JVM的一部分。类装载过程不仅涉及基本的类查找和导入,还包含了链接、验证、准备、解析和初始化等多...

    java类加载器实例

    类加载器是 Java 语言的一个创新,也是 ...不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试 ClassNotFoundException和 NoClassDefFoundError等异常。

    Java类文件动态装载

    本篇文章将深入探讨Java类文件的动态装载机制,并结合源码分析其工作原理。 Java类的装载过程主要由类加载器(ClassLoader)来完成,这是一个关键组件,它负责查找、加载和初始化类。Java类加载器分为系统类加载器...

    深入研究Java 的类加载机制

    Java 类的动态装载机制是Java 虚拟机的一项核心技术,可以在运行时刻动态地加载或替换系统的 某些功能模块,而不影响系统其它功能模块的正常运行。介绍了Java 虚拟机中类的动态装载机制的原理、实现 及应用,分析了...

    jvm类装载器原理

    《JVM类装载器原理详解》 Java的JVM(Java Virtual Machine)类装载器是...总之,深入理解JVM的类装载器原理,不仅有助于我们更好地理解和调试Java程序,也有助于我们在实际开发中实现更加高效和灵活的类管理机制。

    java之jvm学习笔记五(实践写自己的类装载器)

    通过实践编写自己的类装载器,不仅可以加深对JVM内部工作原理的理解,还能锻炼对Java反射、字节码操作、类加载机制的掌握。这是一个提升Java技术水平的重要步骤,也是成为一名资深Java开发者必备的技能之一。

    java装载工具及方法指导

    Java装载工具及方法是Java编程中的重要组成部分,它关乎到程序的运行时环境以及类的加载与执行。本文将深入探讨Java的装载工具——类加载器(ClassLoader)以及相关的加载方法,旨在为开发者提供详尽的指导。 首先...

    动态编译、加载java类

    2. **Java类加载机制**: Java的类加载机制是基于“类装载器”(ClassLoader)的。JVM使用类加载器将.class文件加载到内存中,转换为Class对象。默认有三个内置的类加载器:Bootstrap ClassLoader(引导类加载器)、...

    java动态代理机制分析及拓展

    Java 动态代理机制是Java语言提供的一种在运行时创建代理类和代理对象的机制,主要涉及`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。动态代理通常用于实现AOP(面向切面编程)、事件...

Global site tag (gtag.js) - Google Analytics