好久都没有更新了,一是因为懒,二别人的技术博客都写的非常好了,有一些自己在学习的技术都有很多大神写的非常清晰了,以至于qq收藏里藏了一堆别人的技术博客地址,自己却不咋写,哈哈,这里就当是一个记笔记的地方吧!
JVM 中类的装载是由类加载器(ClassLoader) 和它的子类来实现的,Java中的类加载器是一个重要的Java 运行时系统组件,它负责在运行时查找和装入类文件中的类。
由于Java的跨平台性,经过编译的Java源程序并不是一个可执行程序,而是一个或多个类文件。当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。
加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。加载完成后,Class对象还不完整,所以此时的类还不可用。接下来进入连接阶段。
连接,包括三个阶段:
1.验证(确保Class文件中的字节流包含的信息符合当前虚拟机的要求)
2.准备(为静态变量分配内存并设置默认的初始值)
3.解析(将符号引用替换为直接引用)
初始化,包括两个阶段:
1.如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;
2.如果类中存在初始化语句,就依次执行这些初始化语句。
以上可参考博客
类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader的子类)。从JDK 1.2开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的Bootstrap是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会向Java程序提供对Bootstrap的引用。下面是关于几个类加载器的说明:
a)Bootstrap:一般用本地代码实现,负责加载JVM基础核心类库(rt.jar);
b)Extension:从java.ext.dirs系统属性所指定的目录中加载类库,它的父加载器是Bootstrap;
c)System:又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。它从环境变量classpath或者系统属性java.class.path所指定的目录中记载类,是用户自定义加载器的默认父加载器。
下面是一个自定义类加载器
package testsomething; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class MyClassLoader extends ClassLoader { private String name; // 类加载器的名字 private String path = "d://"; // 加载类的路径 private final 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; } /** * 将class文件作为二进制流读取到byte数组中去 * * @param name * @return */ private byte[] loadClassData(String name) { byte[] data = null; name = name.replace(".", File.separator); // 这里使用了java7的try-with-resources语句 // 代码简单了很多 try (InputStream in = new BufferedInputStream(new FileInputStream( new File(path + name + fileType))); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { int ch = 0; while (-1 != (ch = in.read())) { baos.write(ch); } data = baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } return data; } /** * JVM调用的加载器的方法 */ @Override protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] data = this.loadClassData(name); return this.defineClass(name, data, 0, data.length); } public static void main(String[] args) throws Exception { MyClassLoader loader1 = new MyClassLoader("loader1"); loader1.setPath("d://"); Class<?> clazz = loader1.loadClass("HelloWorld"); Object object = clazz.newInstance(); System.out.println(clazz.getName()); System.out.println(clazz.getConstructors().length); System.out.println(object.toString()); } }
以上。
下面补充一个算是练习题吧
package testsomething; class A{ static{ System.out.print("1"); } public A(){ System.out.print("2"); } } class B extends A{ static{ System.out.print("a"); } public B(){ System.out.print("b"); } } public class Hello{ public static void main(String[] args){ A ab = new B(); ab = new B(); } }
输出结果:
1a2b2b
解释:
1a发生在准备阶段(为静态成员设置默认初始值) 2b2b发生在初始化阶段(先执行未被初始化的父类的构造方法)
相关推荐
自定义类加载器需要继承`java.lang.ClassLoader`类,并重写`findClass`方法来实现自定义加载逻辑。 自定义类加载器的基本流程包括: 1. 重写`findClass`方法,实现类的查找与加载逻辑。 2. 通过调用`super.load...
自定义Java类加载器允许我们根据特定需求扩展默认的加载机制,例如,从非标准位置加载类或者实现动态加载。在Java中,类加载过程分为加载、验证、准备、解析和初始化五个阶段。 首先,让我们了解Java中的默认类加载...
自定义类加载器是Java虚拟机中的一个特殊类加载器,允许用户自定义类加载器,以便于加载特殊的类文件。自定义类加载器可以用来加载加密后的类文件、从数据库中加载类文件等。 Java类加载机制的应用: Java类加载...
在Java中,类加载器(Class Loader)是一项核心机制,用于将字节码(.class文件)加载到JVM中,使其成为运行时的对象。类加载器不仅实现了类的加载功能,还确保了Java程序在多线程环境中的安全性和隔离性。类加载器...
### Java类加载机制详解 #### 一、引言 Java 的类加载机制是 Java 运行时环境(JRE)中的一个重要组成部分。它负责将 Java 类的字节码(.class 文件)加载到 Java 虚拟机(JVM)中,并确保类的正确加载、链接和...
在Java编程语言中,类加载器(ClassLoader)是运行时环境...理解类加载机制并正确实现自定义加载器是提升Java应用开发能力的重要一步。在实际项目中,合理利用类加载器可以解决很多复杂问题,比如模块化、动态更新等。
在 Java 中,我们可以自定义自己的类加载器,以满足特殊的需求。例如,我们可以实现一个基于网络的类加载器,以便从远程服务器加载类。 然而,双亲委派机制也可以被破坏,例如使用 URLClassLoader 加载类,这可以...
Java 类加载机制是Java平台的核心特性之一,它负责将类的字节码加载到Java虚拟机(JVM)中并转换为运行时的类对象。理解这一机制对于优化应用程序性能和解决类相关的错误至关重要。 首先,类加载的过程分为三个主要...
自定义加载器需要重写`findClass()`或`loadClass()`方法。在`MyClassLoader2`示例中,它尝试从指定路径查找类的字节码文件,并通过`defineClass()`方法将字节码转换为Class对象。 ```java public Class<?> find...
- `findClass()`:从Java 1.2开始,自定义类加载器通常只需要重写此方法,当父类加载器找不到类时,此方法会被调用来查找类。 - `defineClass()`:这是一个final方法,用于将字节数组转换为Class对象,实现字节码...
本篇主要基于“译 Java类加载机制(一、二)”的博客内容,深入探讨Java的类加载过程、类加载器以及双亲委派模型。 首先,理解类加载机制的三个基本过程:加载、验证、准备、解析和初始化。加载是找到类的字节码并...
JAVA 类加载机制是Java平台核心特性之一,它关乎到程序的运行时环境和代码的动态加载。理解这一机制有助于开发者解决与对象创建、配置问题、应用程序发布等相关的问题。以下是关于JAVA 类加载机制的详细分析: 首先...
本篇文章将深入探讨Java的双亲模型类加载机制,以及如何通过自定义类加载器实现特定功能。 首先,双亲模型类加载器的工作原理是基于委托机制,即当一个类加载器收到加载类的请求时,它不会立即尝试加载,而是先委托...
通过自定义加载器来加载加密过的 Java 类文件,可以实现快速的部署二级网站,增强网站管理平台的灵活性和可扩展性。 Java 动态类加载机制的优点包括: * 可以在运行时加载类文件,不需要重新启动应用程序 * 可以...
Java 类加载机制主要由类加载器完成。JVM内置了三种预定义的类加载器: 1. **启动类加载器(Bootstrap ClassLoader)**:这是最基础的类加载器,由本地代码实现,负责加载JDK的`<JAVA_HOME>\lib`目录下的核心类库,...
Java加壳技术是一种保护Java程序不被轻易反编译或篡改的安全手段,它通过自定义类加载器来实现对原始字节码的包装。在Java中,类加载器是负责加载类到JVM(Java虚拟机)的核心组件。自定义类加载器允许开发者根据...
在这个例子中,`EncryptedClassLoader`是我们的自定义加载器,它覆盖了`findClass`方法以处理加密的类。`main`方法中,我们使用`Class.forName`加载类,并传入我们的自定义类加载器。找到main方法后,通过反射调用它...
Tomcat,作为广泛使用的Java Servlet容器,它自定义了一套类加载机制,以满足Web应用程序的特殊需求。下面我们将深入探讨Java类加载器以及Tomcat中的类加载器。 在Java中,类加载器主要分为三个层次:Bootstrap ...