Java类加载器特点的具体介绍

开发 后端
Java类加载器需要我们学习的知识还有很多,我们在不断的学习中就会发现很多在使用中的小窍门。下面我们就详细的看看如何才能更好的使用。

Java类加载器一个我们经常使用的优秀语言,但是在我们使用的过程中有不少的问题需要我们解决。下面我们就详细的来看看相关问题的解决方法。想大家有所收获。

Java类加载器的特性:

每个ClassLoader都维护了一份自己的名称空间, 同一个名称空间里不能出现两个同名的类。

为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 " 双亲委派的加载链 " 结构。

类图中, BootstrapClassLoader是一个单独的java类, 其实在这里, 不应该叫他是一个java类。因为,它已经完全不用java实现了。它是在jvm启动时, 就被构造起来的, 负责java平台核心库。

自定义类加载器加载一个类的步骤

ClassLoader 类加载逻辑分析, 以下逻辑是除 BootstrapClassLoader 外的类加载器加载流程:

 

  1. // 检查类是否已被装载过  
  2. Class c = findLoadedClass(name);  
  3. if (c == null ) {  
  4. // 指定类未被装载过  
  5. try {  
  6. if (parent != null ) {  
  7. // 如果父类加载器不为空, 则委派给父类加载  
  8. c = parent.loadClass(name, false );  
  9. } else {  
  10. // 如果父类加载器为空, 则委派给启动类加载加载  
  11. c = findBootstrapClass0(name);  
  12. }  
  13. } catch (ClassNotFoundException e) {  
  14. // 启动类加载器或父类加载器抛出异常后, 当前类加载器将其  
  15. // 捕获, 并通过findClass方法, 由自身加载  
  16. c = findClass(name);  
  17. }  

线程上下文类加载器

java默认的线程上下文类加载器是 系统类加载器(AppClassLoader)。

 

  1. //Now create the class loader to use to launch the application  
  2. try {  
  3. loader = AppClassLoader.getAppClassLoader(extcl);  
  4. } catch(IOException e) {  
  5. throw new InternalError(  
  6. "Could not create application class loader" );  
  7. }  
  8. //Also set the context class loader for the primordial thread.  
  9. Thread.currentThread().setContextClassLoader(loader); 

 

Java代码

 

  1. //Now create the class loader to use to launch the application  
  2. try {  
  3. loader = AppClassLoader.getAppClassLoader(extcl);  
  4. } catch (IOException e) {  
  5. throw new InternalError(  
  6. "Could not create application class loader" );  
  7. }  
  8. //Also set the context class loader for the primordial thread.  
  9. Thread.currentThread().setContextClassLoader(loader); 

 

以上代码摘自sun.misc.Launch的无参构造函数Launch()。使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.典型的例子有, 通过Java类加载器上下文来加载第三方库jndi实现, 而不依赖于双亲委派.大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。还有一些采用 hotswap 特性的框架, 也使用了线程上下文类加载器, 比如 seasar (full stack framework in japenese).#t#

线程上下文从根本解决了一般应用不能违背双亲委派模式的问题.使java类加载体系显得更灵活.随着多核时代的来临, 相信多线程开发将会越来越多地进入程序员的实际编码过程中. 因此,在编写基础设施时, 通过使用线程上下文来加载类, 应该是一个很好的选择。当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个,防止因为不同的类加载器, 导致类型转换异常(ClassCastException)。

为什么要使用这种双亲委托模式呢?

因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。以上就是对Java类加载器的详细介绍。

 

责任编辑:张浩 来源: 博客园
相关推荐

2012-02-09 10:31:17

Java

2021-07-05 06:51:43

Java机制类加载器

2009-12-25 14:20:24

宽带无线接入系统

2011-07-12 10:43:20

JAVA类加载

2011-02-25 09:23:00

Java类加载器

2011-07-12 10:24:17

类加载反射

2021-05-08 09:02:19

Java加载器

2009-12-14 13:38:59

VS 类视图

2024-03-12 07:44:53

JVM双亲委托机制类加载器

2010-02-22 16:34:17

WCF性能计数器

2010-03-15 15:02:22

Python type

2016-01-14 09:38:55

Java加载器理解

2010-03-15 08:48:38

Python编辑器

2009-09-07 16:09:19

C#和Java特点

2017-09-04 13:44:00

Java

2010-02-25 14:26:48

WCF特点

2010-01-27 16:41:48

Android特点

2009-12-14 13:56:12

Ruby特点

2024-04-09 08:41:41

JVM类加载Java

2010-03-08 08:39:54

类加载器newJava
点赞
收藏

51CTO技术栈公众号