不同自定义类加载器之间的class能互相调用吗

Class caller = Reflection.getCallerClass(3);

要创建用户自己的类加载器,只需要扩展ja.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名字,返回对应的Class对象的引用。

类加载器有几种 类加载器的种类类加载器有几种 类加载器的种类


类加载器有几种 类加载器的种类


findClass

protected Class findClass(String name)

throws ClassNotFoundException

使用指定的二进制名称查找类。此方法应该被类加载器的实现重写,该实现按照委托模型来加载类。在通过父类加载器检查所请求的类后,此方法将被 loadClass 方法调用。默认实现抛出一个 ClassNotFoundException。

参数:

name - 类的二进制名称

返回:

得到的 Class 对象

抛出:

ClassNotFoundExceptipublic static void main(String args[])on - 如果无法找到类

两个类加载器加载同一个类

如果在上述程式中,如果您使用程式码:

两个类加载器加载同一个类

类与类加载器的关系

这里的“相等”,包括代表类的Class对象的equals()方法,isAssignableForm()方法和,isInstance()方法的返回结果。也包括instanceOf关键字对象所属关系判定等情况。如果没有注意到类加载器的影响,在某些情况下会产生迷惑人的结果。

如例:

结果分析:

用自定义类加载器加载类ClassLoaderTest,与系统默认加载器加载的类进行isInstance比较,结果为flase。

这是因为JVM中存在了两个ClassLoaderTest类,一个是由系统默认类加载器加载的,一个是由自定义类加载器myloader加载的。

虽然都来自同一个class文件,但依然类加载器用于实现类的加载动作,但它在ja中起到的作用远远不仅于类加载阶段。对于任何一个类来说,都需要类本身和加载这个类的类加载器一同确立其在ja JVM中的性。通俗来讲:比较两个类是否相等,只有两个类是由同一个类加载器加载的前提下才有意义。否则,即使两个类来自同一个class文件,但是由于加载他们的类加载器不同,那这两个类就必不相等。是两个的类。

说明判定类相同的条件:1、类加载器相同。 2、class文件相同

--文字和实例均摘抄自《深入理解Ja虚拟机:JVM高级特性与实践》一书

JVM之class加载过程

webman不错

ja虚拟机把描述类的数据从class文件加载到内存,并对数据进行 校验/准备/解析和初始化,最终形成可以被虚拟机直接使用的Ja类型,这个过程被称作虚拟机的类加载机制。

通过上图你可以看到,intece 如同class 一般,会由编译器产生一个的类别档(.class),当类别载入器载入类别时,如果发现该类别继承了其他类别,或是实作了其他介面,就会先载入代表该介面的类别档,也会载入其父类别的类别档,如果父类别也有其父类别,也会一并优先载入。换句话说,类别载入器会依继承体系最上层的类别往下依序载入,直到所有的祖先类别都载入了,才轮到自己载入。

称作虚拟机的类加载机制。

loading -> linking (verification -> preparation -> resolution)-> resolution)->initializing

verification: 校验class文件是否符合标准

preparation: 静态变量分配内存并设初始值的阶段(不包括实例变量)

initializing:静态变量赋初始值

类加载的过程主要分为三个部分:加载、连接、初始化这三个阶段。

类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的ja.lang.Class对象,用来封装类在方法区类的对象。主要步骤可以分为下面的三件事情:

类的加载的最终产品是位于堆区中的Class对象。Class对象封装了类在方法区内的数据结构,并且向Ja程序员提供了访问方法区内的数据结构的接口。加载类的方式有以下几种:

2.加载器

JVM的类加载是通过ClassLoader及其子类来完成的,类的层次关系和加载顺序可以由下图来描述:

1.BootstrapClassLoader(启动类加载器)

在连接里面又可以被分成3个小阶段,分别是:验证,准备,解析

1.验证(目的):

2.验证内容:

验证是连接阶段的步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。验证阶段大致会完成4个阶段的检验动作:

验证阶段是非常重要的,但不是必须的,它对程序运行期没有影响,如果所引用的类经过反复验证,那么可以考虑采用-Xverifynone参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。

3.准备:

在准备阶段,为静态变量的初值为jvm默认的初值,而不是我们在程序中设定的初值。jvm默认为静态变量的初值是这样的

4.解析:

这一阶段的任务就是把常量池中的符号引用转换为直接引用 什么是符号引用,什么是直接引用。

1.工作内容:

JVM负责主要对类变量(类变量就是static修改的变量)进行初始化这里主要对类变量(类变量就是static修改的变量)进行初始化,初始化主要有两个方式:

类初始化时机:只有当对类的主动使用的时候才会导致类的初始化,类的主动使用包括以下六种:

3.初始化顺序:

三、结语:

上面介绍的就是类(class)的加载,包含它的加载、链接、初始化。

Android进阶知识点,我最近整理了许多,里面讲解的非常详细。取

技术进阶手册丶面试题纲丶核心笔记资料。

vue-loader是什么

vue-loader是一个用于处理Vue组件文件的webpack加载器。

vue-loader是一个webpack的加载器,用于处理Vue组件文件。它可以将Vuloading: 把class文件load到内存中,采用双亲委派,主要是为了安全性e单文件组件的模板、脚本和样式打包在一起2.初始化时机:,以便在浏览器中使用。通过vue-loader,我们可以使用类似于模块化的开发方式编写Vue.js应用程序,将组件的模板、脚本和样式分离,提高代码的可维护性和开发效率。

Ja类别载入器

上述编译脚本定义在文件art/runtime/Android.mk中。

1 Ja的动态特性

[plain] view plaincopy在CODE上查看代码片派生到我的代码片

Ja的动态特性有两种,一是隐式的;另一种是显示的。隐式的(implicit)方法就是当程式设计师用到new 这个Ja 关键字时,会让类别载入器依需求载入您所需要的类别,这种方式使用了隐式的(implicit)方法。显式的方法,又分成两种方式,一种是藉由ja.lang.Class 里的forName()方法,另一种则

是藉由ja.lang.ClassLoader 里的loadClass()方法。您可以任意选用其中一种方法。

2 隐式的动态特性

在执行ja文件时,只有单独的变量声明是不会载入相应的类的,只有在用new生成实例时才载入

如示例所示:

public class Main

{A a1 = new A() ;

}类A和B相同,如下:

public class A

{public void print(“using A”);

}编译后,可用ja _verbose:class Main运行,察看输出结果。可以看到JVM只载入了A,而没有载入B.

另外,类的载入只在执行到new一个类时,才载入,如果没有执行到new语句,则不载入。

如://类Off

{public static void main(String[] args)

{Word myword=null;

Excel myexcel=null;

if (args[0].equals("Word"))

{myword = new Word();

}if (args[0].equals("Excel"))

{myexcel = new Excel();

myexcel.start();

}//类Word和Excel基本相同,如下

public class Word

{public void start()

{System.out.println("using word");

在dos命令提示符下,输入ja _verbose Off Excel可以看到JVM只载入Excel类,而不载入Word类。

3 显示的动态特性

3.1 ja.lang.Class里的forName()方法

在上一个Off示例中,进行如下修改:

一 加入Assembly类

public intece Assembly

{public void start();

}二 让Word和Excel类实现该接口

{public void start()

{System.out.println("using word");

三 Off 类如下所示

{public static void main(String[] args) throws Exception

Object o = c.newInstance();

Assembly a = (Assembly)o;

a.start();

在命令提示符下输入ja _verbose Off Word 输出入下:

下面介绍一下 forName 函数, 如果您亲自搜寻Ja 2 SDK 说明档内部对於Class 这个类别的说明,您可以发现其实有两个forName()方法,一个是只有一个参数的(就是之前程式之中所使用的):

public static Class forName(String className)

另外一个是需要三个参数的:

public static Class forName(String name, boolean initialize,ClassLoader loader)

这两个方法,最後都是连接到原生方法forName0(),其宣告如下:

private static native Class forName0(String name, boolean initialize, ClassLoader loader)

throws ClassNotFoundException;

只有一个参数的forName()方法,最後叫用的是:

forName0(className, true, ClassLoader.getCallerClassLoader());

而具有三个参数的forName()方法,最後叫用的是:

forName0(name, initialize, loader);

这里initialize参数指,在载入类之后是否进行初始化,对于该参数的作用可用如下示例察看:

类里的静态初始化块在类次被初始化时才被呼叫,且仅呼叫一次。在Word类里,加入静态初始化块

{static

{System.out.println("word static initialization ");

}public void start()

{System.out.println("using word");

将类Off作如下改变:

{public static void main(String[] args) throws Exception

{Off off= new Off();

ja.lang.Class c = ja.lang.Class.forName(args[0],true,off.getClass().getClassLoader());

System.out.println("类别准备实体化");

Object o = c.newInstance();

Object o2 = c.newInstance();