在我们实际开发中经常会遇到一些问题,比如某些类我们需要动态的加载进java虚拟机的内存区域。
要实现这个功能我们就需要了解java虚拟机的几个类加载器。
Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:
引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader() 来获取它。
除了系统提供的类加载器以外,开发人员可以通过继承 java.lang.ClassLoader 类的方式实现自己的类加载器,以满足一些特殊的需求。
我们平时程序执行的时候在类加载器中寻找类的结构的顺序是:引导类加载器-》 扩展类加载器-》系统类加载器-》我们自定义的一些类加载器,每个类加载器都有自己的空间,同一个加载器里面的类的二进制名字必须是唯一的,当然同一个类也可以存在不同的加载器内存区域里面,不过我们寻找类的时候是按顺序找的,一但找的也就不会继续往下找了,最终也没找到就会报类不存在异常。
我们如果想动态加载类的话就要仿照我们用的服务器如tomcat和weblogic之类的,他们的开发模式也就是把所有的类都加载到自身的类加载器中,当文件被替换的时候他们就重新加载新的class到内存里面去,从而实现了类的动态加载。
以下是个人是实现一个动态加载类的小程序:
Class A 是需要动态加载的一个小程序:
package jvm;
public class A {
public static void doSome(){
System.out.println("测试类的动态加载!");
}
}
我把A.class文件放到D盘,然后通过我自己写的类来动态加载他:
package jvm;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Method;
public class LoaderSomeClass {
public static void main(String[] args) throws Exception {
ClassLoaderSub classLoaderSub = new ClassLoaderSub();
Class clazz = classLoaderSub.getClassByFile("D:/A.class");
System.out.println("类的名字:"+clazz.getName());
System.out.println("类的加载器:"+clazz.getClassLoader());
classLoaderSub.loadClass(A.class.getName());
Object obj = clazz.newInstance();
Method method = clazz.getMethod("doSome");
method.invoke(obj, null);
}
}
class ClassLoaderSub extends ClassLoader{
public Class defineClassByName(String name,byte[] b,int off,int len){
//由于defineClass是protected,所以需要继承后来调用
Class clazz = super.defineClass(name,b,off,len);
return clazz;
}
public Class getClassByFile(String fileName) throws Exception{
File classFile = new File(fileName);
//一般的class文件通常都小于100k,如果现实情况超出这个范围可以放大长度
byte bytes []= new byte[102400];
FileInputStream fis = null;
Class clazz = null;
try {
fis = new FileInputStream(classFile);
int j = 0;
while (true) {
int i = fis.read(bytes);
if (i == -1)
break;
j += i;
}
clazz = defineClassByName(null,bytes,0,j);
} finally{
fis.close();
return clazz;
}
}
}
输出结果为:
类的名字:jvm.A
类的加载器:jvm.ClassLoaderSub@1fb8ee3
测试类的动态加载!
分享到:
相关推荐
这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时将Java源代码(.java)编译成对应的字节码文件(.class),并将其加载到Java虚拟机(JVM)中。以下是对这个主题的详细解析...
Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class文件,动态实现spring bean 的动态加载,并通过UrlClassLoader完成jar和class文件的加载。可以实现jar的热替换。spring的bean动态加载则需要对...
"class文件热加载,上传class文件实现热加载"这个主题主要涉及到Java应用的运行时动态更新机制。下面将详细介绍这个过程及其相关知识点。 1. **Java类加载器**: - Java虚拟机(JVM)通过类加载器来加载类。默认有...
#### 一、Java与JVM中的Class文件加载机制概述 Java作为一种动态性极强的解释型编程语言,在程序运行时,Java虚拟机(JVM)负责将编译生成的`.class`文件加载到内存中进行执行。在Java环境中,每个类(Class)以及...
当我们运行一个JAR文件时,Java虚拟机(JVM)会加载其中的class文件并执行其中的代码。 修改JAR文件中的class文件涉及以下几个步骤: 1. **解压JAR文件**:使用解压缩工具(如WinRAR、7-Zip或命令行的jar命令)将...
这个压缩包`class文件编译器.zip`很可能包含了关于如何将Java源代码编译成`.class`文件的相关工具和信息。`ReadMe.txt`可能是提供编译过程的说明或者编译器使用的指南。 1. **Java源代码与Class文件**: Java源...
总结起来,Android 动态加载Class涉及到的关键技术包括:自定义ClassLoader、Dex文件操作、反射、权限管理以及Android的类加载机制。这一技术在提高程序灵活性和维护性的同时,也需要开发者对Android系统的深入了解...
本压缩包文件提供了两个示例项目,分别展示了JDK动态代理和CGLib动态代理的实现,帮助我们理解这两种技术的工作原理以及它们生成的class文件结构。 首先,我们来详细了解JDK动态代理。JDK动态代理基于Java的接口...
第2节: class文件及类加载详解-01第2节: class文件及类加载详解-01第2节: class文件及类加载详解-01第2节: class文件及类加载详解-01第2节: class文件及类加载详解-01第2节: class文件及类加载详解-01第2节: ...
ClassLoader主要关注的是加载阶段,它根据全限定名(如"java.lang.String")找到对应的.class文件,并将其转换为Class对象。Java提供了三个基础类加载器:Bootstrap ClassLoader、Extension ClassLoader和...
使用`Class.forName()`加载类后,可以调用`newInstance()`方法创建类的实例,然后调用其方法执行动态编译的代码。 以上步骤概括了动态编译字符串成Java并加载到JVM的过程。这个技术虽然强大,但也需要注意安全问题...
在Java开发过程中,有时我们需要查看或理解某个JAR包中未提供源代码的Class文件的内部实现。本文详细介绍了如何在Eclipse环境中反编译Class文件,以便查看对应的源码。 首先,反编译Class文件是为了能理解那些无法...
“class文件反编译工具”是一种实用的开发辅助工具,它允许开发者查看和理解已编译的Java程序内部结构,这对于学习开源库、调试、逆向工程或者分析恶意软件的行为非常有帮助。其中,`jd-gui`是一个常见的开源Java反...
3. **加载class文件**:在jd-gui的窗口中,可以通过菜单栏的"File" -> "Open File"选项,选择你要反编译的.class文件。也可以直接拖拽.class文件到jd-gui的主窗口。 4. **查看反编译结果**:一旦加载成功,jd-gui会...
本文将围绕".class文件反编译工具"这一主题,详细讲解如何将`.class`文件转换为可读的`.java`源文件,并重点介绍解压后的jd-gui-windows-1.4.0工具的使用方法。 首先,了解`.class`文件结构至关重要。每个`.class`...
下面将详细介绍.class 文件反编译到.java 文件的过程,包括反编译工具的使用和反编译后的修改、再编译等步骤。 一、反编译工具的选择 在反编译.class 文件时,需要使用专门的反编译工具。目前有多种反编译工具可供...
在Java开发过程中,有时我们需要查看已编译的`.class`文件来理解代码的执行逻辑,尤其是在遇到异常或问题时,查看字节码有助于排查问题。Eclipse作为一个强大的Java集成开发环境,本身并不直接支持查看`.class`文件...
总之,Java热加载Class文件是提高开发效率的有效手段,它通过动态替换和更新类,使得开发者能够在不重启JVM的情况下观察代码更改的效果。了解并掌握这项技术,对于提升Java开发者的生产力具有重要意义。
3. 加载Class文件:通过菜单或直接拖放Class文件到jd-gui窗口中,程序会自动反编译并显示源代码。 4. 浏览代码:在界面上,你可以逐行浏览反编译后的源码,点击类名或方法名可以跳转到相应的定义。 虽然jd-gui在...
每个class文件的结构遵循特定的规范,以确保JVM能够正确解读并加载。 1. **类文件结构**: - **魔数**:标识文件是否为合法的class文件,固定值0CAFEBABE。 - **版本号**:包括Minor和Major版本号,表示该class...