虚拟机加载类的途径
1、由 new 关键字创建一个类的实例
在由运行时刻用 new 方法载入
如:Dog dog = new Dog();
2、调用 Class.forName() 方法
通过反射加载类型,并创建对象实例
如:Class clazz = Class.forName(“Dog”);
Object dog =clazz.newInstance();
3、调用某个 ClassLoader 实例的 loadClass() 方法
通过该 ClassLoader 实例的 loadClass() 方法载入。应用程序可以通过继承 ClassLoader 实现自己的类装载器。
如:Class clazz = classLoader.loadClass(“Dog”);
Object dog =clazz.newInstance();
三者的区别:
1和2使用的类加载器是相同的,都是当前类加载器。(即:this.getClass.getClassLoader)。3由用户指定类加载器。如果需要在当前类路径以外寻找类,则只能采用第3种方式。第3种方式加载的类与当前类分属不同的命名空间。另外,1是静态加载,2、3是动态加载
两个异常(exception)
静态加载的时候如果在运行环境中找不到要初始化的类,抛出的是NoClassDefFoundError,它在JAVA的异常体系中是一个Error
动态态加载的时候如果在运行环境中找不到要初始化的类,抛出的是ClassNotFoundException,它在JAVA的异常体系中是一个checked异常
Class.forName与ClassLoader.loadClass区别
Class的装载包括3个步骤:加载(loading),连接(link),初始化(initialize).
Class.forName(className)实际上是调用Class.forName(className, true, this.getClass().getClassLoader())。第二个参数,是指Class被loading后是不是必须被初始化。
ClassLoader.loadClass(className)实际上调用的是ClassLoader.loadClass(name, false),第二个参数指Class是否被link。
Class.forName(className)装载的class已经被初始化,而ClassLoader.loadClass(className)装载的class还没有被link。一般情况下,这两个方法效果一样,都能装载Class。但如果程序依赖于Class是否被初始化,就必须用Class.forName(name)了。
例如,在JDBC编程中,常看到这样的用法,Class.forName("com.mysql.jdbc.Driver").
如果换成了getClass().getClassLoader().loadClass("com.mysql.jdbc.Driver"),就不行。
com.mysql.jdbc.Driver的源代码如下:
// Register ourselves with the DriverManager
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
原来,Driver在static块中会注册自己到java.sql.DriverManager。而static块就是在Class的初始化中被执行。
所以这个地方就只能用Class.forName(className)。
对于相同的类,JVM最多会载入一次。但如果同一个class文件被不同的ClassLoader载入,那么载入后的两个类是完全不同的。因为已被加载的类由该类的类加载器实例与该类的全路径名的组合标识。设有 packagename.A Class ,分别被类加载器 CL1 和 CL2 加载,所以系统中有两个不同的 java.lang.Class 实例: <CL1, packagename.A> 和 <CL2, packagename.A>。
本文欢迎转载,但请注明作者与出处
作者:流星
出处:http://blog.sina.com.cn/staratsky
分享到:
相关推荐
本文将通过解析Java虚拟机面试题来深入探讨JVM的多个方面。 首先,理解JDK和JRE的概念对于理解Java环境至关重要。JDK(Java Development Kit)是Java程序设计的核心,它包括Java编程语言、Java虚拟机(JVM)以及...
数据区中保存了程序执行所需的信息,如字节码、被加载类的其他额外信息、程序中的对象、方法的参数、返回值、本地变量、处理的中间变量等。 四、Java 虚拟机的内存结构 Java 虚拟机的内存结构包括方法区(method ...
类加载是Java虚拟机启动时或运行时动态加载类的过程。它由类加载器系统执行,通常分为引导类加载器、扩展类加载器和应用程序类加载器。加载过程包括加载、验证、准备、解析和初始化五个阶段,确保加载的类符合规范且...
《自己动手写Java虚拟机及class文件解析分析工具(java8运行)》是一份深入探讨Java虚拟机(JVM)工作原理以及如何解析与分析Java类文件(.class)的资源。通过使用Go语言实现一个简化的JVM,这份资料旨在帮助读者...
其中,类装载器负责加载类文件,运行时数据区存储线程的工作数据,执行引擎解析并执行字节码,本地方法接口允许JVM调用非Java语言实现的函数,而本地库则包含操作系统特定的功能。 在性能优化方面,Java虚拟机实现...
MiniJavaVM—个Java虚拟机的设计和实现 在本篇文章中,我们将详细介绍 MiniJavaVM 的设计和实现,包括其总体架构、功能、运行环境和开发工具,以及具体的实现步骤。 第一章绪论 Java 虚拟机(Java Virtual ...
Java虚拟机(JVM,Java Virtual Machine)是Java平台的核心组成部分,它负责执行Java程序,为Java代码提供了跨平台的运行环境。Java虚拟机的概念始于Sun Microsystems,现在由Oracle公司继续发展和维护。JVM的设计...
Java虚拟机的运行过程包括加载、验证、准备、解析、初始化等阶段,其中最重要的是解释器和JIT(Just-In-Time)编译器。解释器将字节码逐行解释执行,而JIT编译器会在运行时将热点代码编译成机器码,以提高运行效率。...
- 压缩文件加载:从`.jar`、`.zip`等压缩文件中查找并加载类,自动解析`.jar`文件中的`.class`文件。 - 动态编译:从`.java`源代码文件编译成`.class`文件,然后加载。 类加载器的层次结构包括引导类加载器...
它详尽地探讨了Java虚拟机的工作原理、内存管理、类加载机制、字节码执行以及性能优化等多个核心主题,旨在帮助开发者提升程序的运行效率和稳定性。 1. **Java虚拟机概述**:Java虚拟机是Java平台的核心组件,它...
类加载器在类加载过程中起着关键作用,它们遵循双亲委派模型,从Bootstrap ClassLoader开始,向上委托,直到找到合适的类加载器加载类。开发者还可以自定义类加载器,实现特定的加载逻辑。 总的来说,Java虚拟机的...
通过学习《JAVA虚拟机解读入门》,你将能够了解JVM如何加载和解析类,以及类加载的双亲委托模型。你还将掌握栈帧的工作方式,理解方法调用和返回的过程。此外,书中还会详细介绍垃圾收集的工作原理,包括如何判断...
其中,类加载器扮演着非常重要的角色,从文件系统中加载类文件,并将其加载到 JVM 的内存区域中。 五、结论 Java 虚拟机工作原理详解是 Java 程序执行的核心组件之一。类加载器是 Java 虚拟机中的一种机制,负责将...
2. **类加载机制**:JVM如何找到并加载类文件,包括类加载器、双亲委派模型和类加载过程(加载、验证、准备、解析和初始化)。 3. **内存管理**:JVM内存结构包括堆、栈、方法区等,书中会讲解如何模拟这些区域,...
1. **启动**:当一个包含`public static void main(String[] args)`方法的类被加载时,Java虚拟机就会启动。`main()`方法是程序的入口点,Java虚拟机通过调用这个方法来开始执行程序。 - **主方法**:`main()`...
Java虚拟机(JVM)是Java程序运行的核心,它的内部机制包括了类的加载、链接、初始化等关键过程。在Java编程中,了解这些过程对于优化程序性能、理解和解决类加载问题至关重要。本文将深入探讨Java虚拟机中的类初始...
通过深入学习《Java虚拟机规范(Java SE 7)》,开发者可以掌握JVM的内存结构,理解类加载过程,了解垃圾收集机制,以及如何有效地利用这些知识来编写更高效、更稳定的Java代码。此外,熟悉JVM规范也能帮助开发者...
- **方法区**:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 - **堆**:存放对象实例,所有对象实例以及数组都要在堆上分配。 - **虚拟机栈**:描述的是Java方法执行的内存模型...