当前位置:首页 > 开发 > 编程语言 > 加密解密 > 正文

类的加载ClassLoader

发表于: 2014-10-15   作者:肆无忌惮_   来源:转载   浏览:
摘要: 类加载器ClassLoader是用来将java的类加载到虚拟机中,类加载器负责读取class字节文件到内存中,并将它转为Class的对象(类对象),通过此实例的 newInstance()方法就可以创建出该类的一个对象。   其中重要的方法为findClass(String name)。   如何写一个自己的类加载器呢? 首先写一个便于测试的类Student

类加载器ClassLoader是用来将java的类加载到虚拟机中,类加载器负责读取class字节文件到内存中,并将它转为Class的对象(类对象),通过此实例的 newInstance()方法就可以创建出该类的一个对象。

 

其中重要的方法为findClass(String name)。

 

如何写一个自己的类加载器呢?

首先写一个便于测试的类Student

有一个属性和一个方法

 

package 类的加载;

public class Student {

	int x;

	public void setX(int x) {
		this.x = x;
		System.out.println(x);
	}
}

 

 

 

写一个自己的类加载器。就是读取class文件,并将其实例化为Class对象的一个过程。

但是必须注意,同一个类如果用不同的加载器对其进行多次加载,会产生异常。所以一旦有一个加载器加载过了就不用再进行加载。

 

 

public class MyClassLoder extends ClassLoader {

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {

		Class c = findLoadedClass(name);
		
		// 保证加载的唯一性,如果之前已经被加载过了,就不用再加载了。
		if (c == null) {
			byte data[] = readFile(name);
			c = this.defineClass(data, 0, data.length);
			this.resolveClass(c);// 将对象c交给虚拟机去管理
			System.out.println("加载好了");
		}
		return c;
	}

	/**
	 * 读取指定的class文件的字节数据
	 * 
	 * @param name
	 * @return
	 */
	public byte[] readFile(String name) {
		byte[] bt = null;
		String path = "bin/" + name.replace(".", "/") + ".class";
		System.out.println(path);
		try {
			FileInputStream fis = new FileInputStream(new File(path));
			// // 但是无法确定你会读到多少数据
			// byte bt[] = new byte[100];
			// fis.read(bt);

			// 用字节数组流临时存储数据,可以不管其长度
			ByteArrayOutputStream baos = new ByteArrayOutputStream();

			int t = fis.read();
			while (t != -1) {
				baos.write(t);
				t = fis.read();
			}
			bt = baos.toByteArray();
			fis.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bt;
	}

}

 

 

创建一个加载器

MyClassLoder mcl = new MyClassLoder();

得到这个类

Class c = mcl.findClass("类的加载.Student");

同样,进行方法的测试

Method m = c.getMethod("setX", int.class);

Constructor cs = c.getConstructor();

Object obj = cs.newInstance();

 

m.invoke(obj, 1);

 

输出结果为

bin/类的加载/Student.class

加载好了

1

 

在下面再加一个:

Class c2 = mcl.findClass("类的加载.Student");

Method m2 = c2.getMethod("setX", int.class);

Constructor cs2 = c.getConstructor();

Object obj2 = cs2.newInstance();

 

m2.invoke(obj2, 1);

System.out.println(c==c2);

输出结果为

bin/类的加载/Student.class

加载好了

1

1

 

true

 

可以发现都是同一个类

 

Class c3 = Class.forName("类的加载.Student");
System.out.println(c);
System.out.println(c3);
Constructor cs3 = c3.getConstructor();
Object obj3 = cs3.newInstance();
System.out.println((Student)obj2);

 输出结果为:

class 类的加载.Student

class 类的加载.Student

java.lang.ClassCastException: 类的加载.Student cannot be cast to 类的加载.Student

at 类的加载.Test.main(Test.java:33)

 

也就是说不能重复对其加载。

类的加载ClassLoader

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
静态库、动态连接库 程序编制一般需经编辑、编译、连接、加载和运行几个步骤。在我们的应用中,有一
当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构: bootstrap classlo
原文转自: http://yueyemaitian.iteye.com/blog/1185339 一、ClassLoader 负责装载class文件;这个
可视化编辑器做的太垃圾了 , 把word笔记放在了附件里面 ClassLoader主要作用 : 将.class后缀的字节
“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到java虚拟机外部去实现,以便让
一、什么是 类加载器(ClassLoader)? 类加载器(ClassLoader),用来加载 Java字节码(.class)到 Java
使用JAVA到现在,总结下类加载器: 1、什么是类加载器? 顾名思义,类加载器就是加载类的工具。 2、
(1) JVM中ClassLoader的类型 JVM预定义了三种类型类加载器,当一个 JVM 启动的时候,Java 缺省开始
Java应用环境中不同的class分别由不同的ClassLoader负责加载。 一个jvm中默认的classloader有Bootst
最近开始投入时间,进行OSGI的学习,买了林昊的《OSGI的原理与实践》,并且参考51cto上的文章等其他
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号