java类装载机制 问题

问题描述

ClassName(自己写的一个类).class.getClassLoader()与Object.class.getClassLoader()好象是不同的,他们有什么区别?

解决方案

又详细查了一下资料:启动类装载器(Bootstrap Loader:C编写的),标准扩展类装载器(Extended Loader:java编写的),类路径装载器(AppClassLoader:java编写的)由于启动类装载器(Bootstrap Loader)是用C编写的所以调用它的时候会返回null测试代码:Object o=new Object();Class c=o.getClass();ClassLoader loader=c.getClassLoader();System.out.println(loader);输出为null新建一个类Test,测试它的加载器。Test o=new Test();Class c=o.getClass();ClassLoader loader=c.getClassLoader();System.out.println(loader);输出为sun.misc.Launcher$AppClassLoader@19821f结果与我预想的一样,那么如何验证我之前的言论呢,即引用而MyClass.class的加载器调用的是类路径装载器,当MyClass.class请求加载的时候,JVM会看启动类装载器,标准扩展类装载器这两个加载器有没有加载这个类,如果加载了那么就放弃当前的这个类加载器,由于之前没有使用启动类装载器,标准扩展类装载器加载这个类,所有JVM还会用类路径装载器加载我们做个实验,建一个类Test.javapublic class Test {/** * @param args */public static void main(String[] args) {/*Coffee coffee=new Coffee();coffee.prepareRecipe();*/Test o=new Test();Class c=o.getClass();ClassLoader loader=c.getClassLoader();System.out.println(loader);}}编译之后copy到Java_home 的classes目录下,如果没有就建一个,之后把编译好的Test.class放到这个目录里。之后在cmd控制台java的bin目录下运行java -cp ./classes Test看看结果,在我的机器上是null,之后在放到c盘根目录运行,发现是sun.misc.Launcher$AppClassLoader@18d107f这就说明如果所加载的类在java的根目录下的某个目录运行,它调用的classLoader就是BootstrapLoader 而其他目录就是类路径加载器了,而如果你想知道在哪个目录下会调用BootstrapLoader的话用这句就可以看到System.out.println(System.getProperty("sun.boot.class.path"));当然用BootstrapLoader性能要好一点,毕竟是C写的呀
解决方案二:
loader是根据类的extends关系一级一级加载的。当然你要是用Object.class那就根loader
解决方案三:
classloader(类加载器)分为4中:启动类装载器,标准扩展类装载器,类路径装载器和网络类装载器这4中加载的优先级从高到底。其中long包中的类被启动类装载器加载,而MyClass.class的加载器调用的是类路径装载器,当MyClass.class请求加载的时候,JVM会看启动类装载器,标准扩展类装载器这两个加载器有没有加载这个类,如果加载了那么就放弃当前的这个类加载器,由于之前没有使用启动类装载器,标准扩展类装载器加载这个类,所有JVM还会用类路径装载器加载,这时MyClass.class.getClassLoader()得到的就是类路径装载器,而Object使用的是启动类装载器,所以就是不同的。
解决方案四:
class.getClassLoader() returns which ClassLoader Object load it.YourClass 可能是被什么 JarClassLoader啦加载的(纯属猜测), Object 可能是jdk较底层的什么ClassLoader加载的,某些时候可以自定义ClassLoader的,那么用YourClassLoader load 的SomeClass,所对应的 SomeClass.class.getClassLoader() 就是你YourClassLoader。我一般都用 Thread.currentThread().getContextClassLoader() 来加载ClassPath Resource,一直没有深究,没啥问题,用SomeClass.class.getClassLoader() 加载往往找不到,也没管它。

时间: 2024-09-25 09:37:19

java类装载机制 问题的相关文章

JAVA类继承机制代码

注意父子类的初始化顺序也~~~还有,MAIN函数在哪个类里,就用哪个类来命名文件: 代码: 1 class Parent { 2 private int num = 1; 3 public Parent() { 4 System.out.println("Now,initial parent calss."); 5 } 6 public void test() { 7 System.out.println("This is the parent's test method.&

在Java中用类装载框架控制类加载

摘要 通过构建一个能够把Java类装载隔离到一个指定的jar文件中的类装载组件容器框架,你可以确保运行时刻会装载你期望的组件版本. Java的类装载框架强有力且具有灵活性.它允许应用程序存取类库而不必链接到静态的"include"文件.代之的是,它能够从指定位置装载包含库类和资源的档案文件,例如由CLASSPATH环境变量所定义的目录和网络位置.由系统来动态地解析对类和资源的运行时刻参考,从而简化了更新和版本发行.然而,每一个库都有其自己的依赖性集合-并且由开发者和发布人员来保证他们的

Java中的类反射机制

一.反射的概念 :反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩.其中LEAD/LEAD++ .OpenC++ .MetaXa和OpenJava等就是基于反射机制的语言.最近,反射机制也被应用到了视窗系统.操作系统和文件系统中. 反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学

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

一.引言 Java虚拟机(JVM)的类装载就是指将包含在类文件中的字节码装载到JVM中, 并使其成为JVM一部分的过程.JVM的类动态装载技术能够在运行时刻动态地加载或者替换系统的某些功能模块, 而不影响系统其他功能模块的正常运行.本文将分析JVM中的类装载系统,探讨JVM中类装载的原理.实现以及应用. 二.Java虚拟机的类装载实现与应用 2.1 装载过程简介 所谓装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造代表这个类或是这个接口的class对象的过程,其中类或接口的名称是

设计-java 字段扩展机制 类扩展机制

问题描述 java 字段扩展机制 类扩展机制 当要求数据库中的一个表里需要进行字段扩展时,如何能让po层中的各个实体也能一起达到扩展的效果呢,数据库里面的表又该如何设计 解决方案 本文转载自:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 简介:? 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java 动态代理运作过程,希望能帮助读者加深对 Java

JAVA不可变类(immutable)机制与String的不可变性(推荐)_java

一.不可变类简介 不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值.如JDK内部自带的很多不可变类:Interger.Long和String等. 可变类:相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类. 二.不可变类的优点 说完可变类和不可变类的区别,我们需要进一步了解为什么要有不可变类?这样的特性对JAVA来说带来怎样的好处? 1.线程安全 不可变对象是线程安全的,在线程之间可以相互共享,不需要利用特殊机制来保证同步问题,因

jvm系列(一):java类的加载机制

java类的加载机制   1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个类被"首次主动使用"时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载

浅析java的SPI机制

1 SPI机制简介 SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的.在java.util.ServiceLoader的文档里有比较详细的介绍.简单的总结下java spi机制的思想.我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块.jdbc模块的方案等.面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码.一旦代码里涉及具体的实现类,就违反了可拔插的原则

Java语言安全机制在移动Agent中的应用

随着Internet覆盖范围的日益扩大,有价值的信息资源在不断的增长,对网络的高效性.智能性.主动性和灵活性提出了更多的要求,对于如何捆绑分布异构环境中信息源的问题变得越来越突出.在网络分布式系统的实际应用中,一般采用Server/Client结构,在这种结构中,运行于Server和Client上进程间的通信是通过信息传送和远程过程调用(RPC)实现的,一般是同步实现的,即Client向服务器发出请求后就挂起本地进程而等待结果,远地Server按要求执行完所要求的数据处理后返回结果,当本地进程得