`

深入理解classloader

    博客分类:
  • JVM
 
阅读更多
一、获取Class的方法

1.直接用(类名.class)
2.对象.getClass()
3.Class.forName("类的全限定名")
     Class c = String[].class;
		System.out.println("c===>"+c);
		  
		c = new String[1].getClass();   
		System.out.println("c===>"+c);
	//JVM对Array的实际类名编码为: 左括号 + 类别代码 + 类名 

		try {
			c = Class.forName("[Ljava.lang.String;");
	
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 


输出结果为:
c===>class [Ljava.lang.String;
c===>class [Ljava.lang.String;
c===>class [Ljava.lang.String;


我们看下其他的数组类名:
System.out.println("byte[]: " + byte[].class.getName());   
		System.out.println("char[]: " + char[].class.getName());   
		System.out.println("int[]: " + int[].class.getName());   
		System.out.println("long[]: " + long[].class.getName());   
		System.out.println("double[]: " + double[].class.getName());   
		System.out.println("float[]: " + float[].class.getName());  


运行结果如下为:
byte[]: [B
char[]: [C
int[]: [I
long[]: [J
double[]: [D
float[]: [F


系统默认的classloader如何获取?
   ClassLoader.getSystemClassLoader()

从运行结果可以看到系统默认使用sun.misc.Launcher$AppClassLoader这个ClassLoader。

classloader加载类的方法:ClassLoader.loadClass(String className) 

如下例子:


public class User {

	private String name;
	private Integer age;
	
	public User(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public User() {
	}
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	
	
	public void sayHello()
	{
		System.out.println("Hello,I am "+name+","+age+" years old.");
	}
	
	
}

 



//测试类中的方法
private static void test2()
	{
	   ClassLoader cl=	ClassLoader.getSystemClassLoader();  
	   System.out.println("cl===> " + cl);
	   try {
		Class clazz = cl.loadClass("com.test.jvm.classloader.User");
	    User user =(User)clazz.newInstance();
		user.sayHello();
		
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		System.out.println("class com.test.jvm.classloader.User not found!");
	} catch (InstantiationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
  



运行结果发现 已经调用sayHello方法了

二、自定义classloader

classloader加载顺序:
⑴首先执行一次检查,查看客户程序请求的类是否已经由当前的类装入器装入。如果是,则返回已装入的类,请求处理完毕。JVM缓冲了类装入器装入的所有类,已经装入的类不会被再次装入。

 ⑵如果尚未装入类,则装入类的请求被委托给父类装入器,这个操作发生在当前的类装入器尝试装入指定的类之前。委托装入类的操作一直向上传递,直至bootstrap类装入器,如前所述,bootstrap类装入器是处于树形结构的顶层,它不再有可委托的父类装入器。

 ⑶如果父类装入器未能装入指定的类,则当前的类装入器将尝试搜索该类。每一个类装入器有预定义的搜索和装入类的位置。例如,bootstrap类装入器搜索 sun.boot.class.path系统属性中指定的位置(包括目录和zip、jar文件),system类装入器搜索的位置由JVM开始运行时传入的CLASSPATH命令行变量指定(相当于设置java.class.path系统属性)。如果找到了类,则类装入器将类返回给系统,请求处理完毕。


三、classloader的命名空间

*在JVM当中,ClassLoader会被当成命名空间来分隔各自加载的类*

# 项目中可以使用不同的ClassLoader来加载包名、类名完全相同的Class,但是这两个Class的内容可以完全不一样。

# 即使是同一个Class文件,如果被两个不同的ClassLoader来加载,那么在JVM中它们相互独立,不算是同一个Class。

第一种情况我们可能会经常遇到,比如使用开源框架时,有的框架里面可以看到对同一个项目有多个不同版本的依赖,有的地方使用版本x,有的地方使用版本y,x与y的包名,类名都一样,但里面的内容可以已经不同,却可以相安无事,这就是由于它们运行在各自独立的ClassLoader当中









分享到:
评论

相关推荐

    深入理解ClassLoader工作机制.docx

    JVM内存模型,类加载模式工作机制详细,内存屏障,类从被加载到虚拟机内存中开始,直到卸载出内存为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三...

    理解Java ClassLoader机制

    理解Java ClassLoader机制

    深入了解Java_ClassLoader,Bytecde.pdf

    深入了解Java_ClassLoader,Bytecde.pdf

    ClassLoader加载机制

    该电子书详细介绍了java虚拟机类加载机制,对于深入理解jvm工作原理有很好的帮助作用,对于初学java,有一定工作经验的小伙伴来说是一本提高自身java素养,夯实自己java基本技能的“葵花宝典”。

    深入分析Java Web技术内幕 修订版

    《深入分析Java Web技术内幕(修订版)》不仅介绍这些技术和框架的工作原理,而且结合示例来讲解,通过通俗易懂的文字和丰富、生动的配图,让读者充分并深入理解它们的内部工作原理,同时还结合了设计模式来介绍这些...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段27讲、wait和sleep的本质区别是什么,深入分析(面试常见问题).mp4 │ 高并发编程第一阶段28讲、线程生产者消费者的综合实战结合Java8语法.mp4 │ 高并发编程第一阶段29讲、如何实现一个...

    Java面试专属视频

    面试必考之HashMap源码分析与实现 ,微服务架构之Spring Cloud Eureka 场景...锁、分布式锁、无锁实战全局性IDSpringMvc深入理解源码分析 Nosql Redis Jedis常用命令 JAVA并发编程之多线程并发同步业务场景与解决方案

    Java常用基础知识-kaic.docx

    《深入理解java虚拟机》 2、对java“书写一次,到处运行”(Write once, run anywhere)的理解? 一次编译、到处运行”说的是Java语言跨平台的特性,Java的跨平台特性与Java虚拟机的存在密不可分,可在不同的环境中...

    全面解析Java类加载器

    深入理解和探究Java类加载机制—-  1.java.lang.ClassLoader类介绍  java.lang.ClassLoader类的基本职责是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个Java 类,即 ...

    Java虚拟机类装载:原理、实现与应用

    类的动态装载机制是JVM的一...本文介绍了JVM中类装载的原理、实现以及应用,尤其分析了ClassLoader的结构、用途以及如何利用自定义 的ClassLoader装载并执行Java类,希望能使读者对JVM中的类装载有一个比较深入的理解。

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ │ 4.SpringMvc深入理解源码分析-悟空.mp4 │ │ │ ├─5.Nosql Redis Jedis常用命令 │ │ 5.Nosql Redis Jedis常用命令-悟空.mp4 │ │ │ ├─6.互联网系统垂直架构之Session解决方案 │ │ 6.互联网系统...

Global site tag (gtag.js) - Google Analytics