`
littie1987
  • 浏览: 135358 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java中类的加载

    博客分类:
  • Java
阅读更多

      今天遇到一个奇怪的现象,我把环境变量里的classpath删除掉之后仍然可以执行java程序(path属性没有删除)。

后来终于明白了,这是java的类加载顺序支配的。

      java虚拟机加载一个类分为以下三种顺序:

      1:Bootstrap   2:Extension   3:Users  

     

     一: Bootstrap:在java启动时载入的类,主要是一些重要的jdk的jar文件。比如rt.jar。这个jar文件包含了jdk的一些基础类库,比如我们熟知的java.lang,java.util等等都包含在rt.jar文件里。这个文件是Bootstrap负责加载的,也就是说我们不需要在项目中手动导入这个jar文件,也不需要在classpath里将他添加进去(他的实际目录为%JAVA_HOME%\jre\bin\rt.jar)。所以就可以解释我遇到的那个奇怪的问题了。没有classpath,一些基本的程序还是可以运行的。当然,Bookstrap不止装载rt.jar一个jar文件。要想知道他都加载了哪些类,可以用如下方法打印:System.out.println(System.getProperty("sun.boot.class.path"));。打印结果如下:

C:\Program Files\Java\jdk1.6.0_05\jre\lib\resources.jar;C:\Program Files\Java\jd
k1.6.0_05\jre\lib\rt.jar;C:\Program Files\Java\jdk1.6.0_05\jre\lib\sunrsasign.ja
r;C:\Program Files\Java\jdk1.6.0_05\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.
6.0_05\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_05\jre\lib\charsets.jar;C:
\Program Files\Java\jdk1.6.0_05\jre\classes

 也就是说,在java启动的时候就已经加载了这么多的类。只要你的程序引用到的类都在这些jar文件里有的话,那就不需要设置什么classpath,更不手动需要导入jar包。

 

二:Extension:如果在Bootstrap的路径里找不到所要的类怎么办?那么这时java虚拟机就会去ext目录下找。具体的目录为%JAVA_HOME%\jre\lib\ext。我们可以试验一下。在ext目录里有一个dt.jar,里面有一个类:javax.swing.BoxBeanInfo。如果我们尝试去加载这个类,按照加载顺序,它会去ext目录下找。看一个程序:

public class tet{
public static void main(String[] args)throws ClassNotFoundException
{

ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class lo = loader.loadClass("javax.swing.BoxBeanInfo");
System.out.println(lo.getClassLoader());
		
}
}

 它的打印结果是:sun.misc.Launcher$ExtClassLoader@addbf1,很明显,他是由ExtClassLoader类加载器进行加载的。因为如果是Bootstrap加载的类,在打印它的类加载器的时候会是null。

 

三:Users :如果所需要的类在以上的目录里都没有,比如你想要一个spring的BeanFactory类,那JDK本身是不可能带的,所以必须由外部导入。由外部导入又有好几种方法,但是java虚拟机的搜索顺序是:

      1:默认的User   classes   .   (dot)   就是指当前目录。

      2:系统变量   CLASSPATH   所指定的类库,该变量覆盖(override)默认的User   classes。

      3:用命令行参数   -cp   或   -classpath指定的类库。这个时候覆盖默认的User   classes   和CLASSPATH变量。

      4:通过-jar   参数指定的jar文件。此时覆盖上面的三种情况,如果使用这种情况,所有的类文件必须来自指定的jar            文件

由此可见,我们平时将一个jar文件放到当前工程的lib目录下,就是第一种搜索顺序,所以如果你不嫌麻烦,完全可以将他设置到classpath之下,当然我们实际不会这么干。此时如果我们打印它的类加载器就应该是ApplicationClassLoader。

 

另外需要说明的是:ApplicationClassLoader的父加载器是ExtClassLoader,ExtClassLoader的父加载器是Bootstrap。但是,打印Bootstrap的类的加载器的的时候往往显示null,好像没有一样,其实打印null就表示是Bootstrap。另外,java的类加载是采用委托机制,即遇到一个类要加载,它不会用子加载器进行加载,而是将请求上述到父加载器,如果父加载器没有找到,就再上述到更高一级的父加载器,一直到Bootstrap为止。如果没有找到,就按照刚才的路径往下转。直到找到为止。所以,如果一个类在classpath里有,在Ext目录下也有,那么加载他的类加载器一定是ExtClassLoader。

我们再来看上面的那个程序:

public class tet{
public static void main(String[] args)throws ClassNotFoundException
{

ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class lo = loader.loadClass("javax.swing.BoxBeanInfo");
System.out.println(lo.getClassLoader());
		
}
}

 

这次我们将在ext目录下的dt.jar文件剪切掉,将他放到%JAVA_HOME%\lib目录下,并且将他设置到classpath环境变量里面。这次我们再打印的话,结果为:sun.misc.Launcher$AppClassLoader@19821f,他的类加载器显然已经变了。这就证明了在classpath里的类是有ApplicationClassLoader加载的,他属于用户自己的类。

分享到:
评论

相关推荐

    springboot+java类热加载

    在Java中,类加载器负责查找并加载类到Java虚拟机中。我们可以通过自定义类加载器来实现热加载。例如,`MemoryClassLoader.java`可能就是一个自定义类加载器的实现,它可以在内存中动态加载或更新类。 **JarinJAR**...

    java类加载器

    在Java中,类加载器(Class Loader)是一项核心机制,用于将字节码(.class文件)加载到JVM中,使其成为运行时的对象。类加载器不仅实现了类的加载功能,还确保了Java程序在多线程环境中的安全性和隔离性。类加载器...

    Java虚拟机类加载顺序

    在Java开发中,了解类是如何被加载到Java虚拟机(JVM)中的至关重要。本文将详细介绍JVM中的类加载顺序及其背后的原理,帮助读者理解这一过程,并掌握如何利用类加载机制解决实际问题。 #### 二、类加载器层次结构 ...

    Java中类加载过程全面解析

    "Java 中类加载过程全面解析" Java 中类加载过程是 Java 语言中一个非常重要的机制,它负责将类文件加载到内存中,以便 JVM 可以使用这些类。类加载过程是一个复杂的过程,涉及到多个步骤和机制。下面将对 Java 中...

    java类加载器实例

    它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java Applet 需要从远程下载 Java 类文件到浏览器中并执行。现在类加载器在 ...

    自定义Java类加载器

    Java类加载器是Java虚拟机(JVM)的关键组成部分,它负责查找并加载类到内存中,使得程序能够运行。自定义Java类加载器允许我们根据特定需求扩展默认的加载机制,例如,从非标准位置加载类或者实现动态加载。在Java...

    java类加载器-tomcat中的类加载器

    Java 类加载器是Java虚拟机(JVM)的核心组成部分,它负责将编译后的字节码文件(.class文件)加载到JVM中并转换为运行时的数据结构。Tomcat,作为广泛使用的Java Servlet容器,它自定义了一套类加载机制,以满足Web...

    Java类加载器原理

    Java 类加载器是Java虚拟机(JVM)的核心组成部分,它负责将类的字节码加载到内存中并转换为可执行的Java类。类加载器的作用不仅仅是加载类,还包括确保类的唯一性,避免重复加载,并且遵循特定的加载顺序。以下是对...

    Java的类加载器

    Java的类加载器是Java虚拟机(JVM)的核心组件之一,它负责将类的字节码从磁盘、网络或其他数据源加载到内存中,并转换为可执行的Java对象。类加载器不仅关乎程序的运行,还在实现动态加载、插件系统等方面发挥着...

    Java类加载内幕详细讲解

    类加载器是Java运行时环境的重要组成部分,负责加载类到JVM中,并确保类的正确加载与隔离。类加载器的基本结构如下: 1. **引导类加载器**(Bootstrap Class Loader):这是系统默认的类加载器,负责加载JRE/lib/rt...

    Java类动态加载(一)——java源文件动态编译为class文件

    在Java编程中,类动态加载是一项重要的技术,它允许程序在运行时根据需要加载新的类,从而提高了灵活性和可扩展性。这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时...

    Java类加载器.pdf

    Java类加载器是Java运行时环境的一个关键组成部分,负责将类文件(.class)从各种来源加载到JVM中。它不仅管理类的生命周期,还确保了类的正确加载和初始化,是Java动态特性的基石。 #### 类加载器的工作原理 Java...

    类加载器(java)

    Java中的类加载器是JVM(Java虚拟机)的核心组件之一,它们负责将.java源代码编译成的.class字节码文件加载到JVM中,从而使得程序能够运行。类加载器不仅涉及到程序的正常执行,还与Java的动态加载、模块化系统以及...

    深入研究Java类加载机制 深入研究Java类加载机制

    Java中的类加载器遵循一个原则叫做“父母委托模型”,即当一个类加载器收到类加载请求时,首先将加载任务委托给父类加载器,只有当父类加载器无法完成加载时才会尝试自己加载。 这种设计模式的好处在于避免了类的...

    Java之——类热加载

    传统的Java应用程序在启动时,由JVM(Java虚拟机)通过类加载器将类加载到内存中,一旦加载完成,除非程序退出,否则这些类通常不会被重新加载。然而,在开发过程中,我们可能希望在不重启应用的情况下,对已加载的...

    java应用程序类加载器,ClassLoader for java Application

    Java应用程序类加载器是Java平台的核心组成部分之一,它负责加载应用程序中的类到JVM(Java虚拟机)中,使得程序能够执行。理解类加载器的工作原理对于深入学习Java编程至关重要。在Java中,类加载器按照层次结构...

    java 类加载器 加密

    Java 类加载器是Java运行时环境的一个重要组成部分,它的主要职责是将编译后的字节码(.class文件)加载到JVM中,使得程序能够运行。类加载器的机制保证了类的唯一性,同时也提供了灵活性,允许我们自定义加载逻辑。...

    Java类加载原理解析

    线程上下文类加载器(Thread Context ClassLoader)则是在特定线程中使用的类加载器,主要用于解决一些应用服务器中类加载的复杂问题,如J2EE容器中的类加载需求。 总的来说,理解Java类加载机制对于排查类加载错误...

Global site tag (gtag.js) - Google Analytics