java 每个类都有一个 classloader

java 每个类都有一个 classloader,第1张

不是这样的,通常只会有一个

Java虚拟机启动时会调用系统类加载器Bootstrap ClassLoader去加载ExtClassLoader和ApplicationClassLoader

ExtClassLoader:自定义的类加载器

ApplicationClassLoader:当你用的某个类时会通过它进行加载,当然你也可以通过代码用自定义的类加载器进行class的加载

加载是指将类加载到java虚拟机中

看下上面的会发现class是Data1类中的一个静态域,这说明在Data1类的多个实例中只有一个class对象,一个对象怎么会返回多个classloader呢。classloader实在class加载到虚拟机时赋上去的

简单写了下,不知道是不是你要的。

import javalangreflectMethod;

import comsunorgapachebcelinternalutilClassLoader;

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

ClassLoader classLoader = new ClassLoader( new String[] { "D:\\Cheiron\\Test\\bin" });//类根路径

Class<> cl = classLoaderloadClass("orgapachecommonslangStringUtils");//类名

Method method = clgetMethod("split", Stringclass, Stringclass);//类的方法

Systemoutprintln(methodgetName());//打印方法名

String[] arrS = (String[]) methodinvoke(null, "a,a", ",");//调用方法

for (String string : arrS) {//打印返回值

Systemoutprintln(string);

}

}

说明:

1)WebappClassLoaderBase及其子类是Tomcat自己实现的类加载器;

2)其默认打破了双亲委派机制,用来实现Tomcat多应用间的隔离;

说明:

1)Bootstrap类加载器:JDK的启动类加载器和扩展类加载器

2)System类加载器:JDK的应用类加载器

3)Common,Catalina,Shared类加载器:是三个URLClassLoader实例,分别指定了不同的path;

4)Webapp类加载器:Tomcat定义的类加载器WebappClassLoaderBase及其自类;

Bootstrap#init方法会执行以下 *** 作:

1)类型为URLClassLoader,未打破双亲委派;

2)其path从catalinaproperties中读取commonloader,serverloader,sharedloader的键值;

3)指定parent关系

Note: tomcat-8556里把common, server, shared合成了一个。

1)通过Digester读取serverxml来初始化Catalina#server;

2)HostRuleSet里设置

3)ContextRuleSet里设置设置Host的Context为StarndardContext,然后设置StandardContext的loader为WebappLoader

4)StandardContext把WebappLoader的context设为自身

5)WebappLoader里把StandardContext的parentClassLoader设为应用类加载器的parent。而StandardContext的parentClassLoader为空,继续找其parent(StandardHOST)的paretClassLoader,即shared类加载器。

Note: JavaSE类加载器默认为启动类加载器。(应用类加载器的构造器里指定了其指向StringclassgetClassLoader();)

官方文档

返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:

ClassforName(className, true, currentLoader)

其中 currentLoader 表示此类的定义类加载器。

例如,以下代码片段返回 javalangThread 类的运行时 Class 描述符。

Class t = ClassforName("javalangThread")

调用 forName("X") 将导致名为 X 的类被初始化。

参数:

className - 所需类的完全限定名。

返回:

具有指定名的类的 Class 对象。

通俗的说就是:获得字符串参数中指定的类,并初始化该类

类装载

类装载就是把一个类或是一个接口的字节码文件,通过解析该字节码来构建代表这个类或是这个接口的实例的过程。 这个字节码文件来源可能是压缩包、网络、运行时编译出的或者自动生成的class文件,jvm spec没有规定必须从什么地方加载。

类装载的两种方式:

1Class c1 = ClassforName ("javalangString");

2ClassLoader cl = new ClassLoader();

Class clloadClass( String name, boolean resolve );

两种装载方法的区别:

不同的类装载器

ClassforName是从指定的classloader中装载类,如果没有指定,也就是一个参数的时候,是从装载当前对象实例所在的classloader中装载类。

而ClassLoader的实例调用loadclass方法,是指从当前ClassLoader实例中调用类,而这个实例与装载当前所在类实例的Classloader也许不是同一个

说白了就是他们实现装载的时候,使用的类装载器的指定是不同的。那为什么使用不同的ClassLoader来装载类呢?

其实使用多个classloader加载类的情况非常常见,比如说我们的app server都是这样的 在Web与EJB间, 他们的classLoader就是不同的,这样做的目的就是为了避免两者间类装载的相互干扰。

是否实例化类

Class的装载分了三个阶段,loading(装载),linking(连接)和initializing(实例化)分别定义在The Java Language Specification的122,123和124。

ClassforName(className)实际上是调用ClassforName(className, true, thisgetClass()getClassLoader())。注意第二个参数,是指Class被loading后是不是必须被初始化。

ClassLoaderloadClass(className)实际上调用的是ClassLoaderloadClass(name, false),第二个参数指出Class是否被link。

区别就出来了。ClassforName(className)装载的class已经被实例化,而ClassLoaderloadClass(className)装载的class还没有被link,所以就更谈不上实例化了。

简单说,就是通过类名反射出类的对象 。

一般情况下,这两个方法效果一样,都能装载Class。但如果程序需要Class被实例化,就必须用ClassforName(name)了。

例如,在JDBC中加载mysql的驱动类时(关于注册jdbc驱动请参看另外一篇文章,jdbc注册驱动的三种方式),ClassforName("commysqljdbcDriver"),如果换成getClass()getClassLoader()loadClass("commysqljdbcDriver"),就不行,因为它只是向jvm装载了Driver并没有实例化,就不能执行响应的 *** 作。

打开commysqljdbcDriver的源代码看看,

//

// Register ourselves with the DriverManager

//

static {

try {

javasqlDriverManagerregisterDriver(new Driver());

} catch (SQLException E) {

throw new RuntimeException("Can't register driver!");

}

}

可以看到,Driver在static块中会注册自己到javasqlDriverManager。而static块就是在Class的初始化中被执行。所以这个地方就只能用ClassforName(className)。

以上就是关于java 每个类都有一个 classloader全部的内容,包括:java 每个类都有一个 classloader、java 如何使用反射 加载指定路径下的类文件(.class)、四、Tomcat类加载器等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9531121.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存