首页 > 代码库 > Java重要技术(30)类加载器之Class类型的相等比较

Java重要技术(30)类加载器之Class类型的相等比较

 

1.1. class类的相等比较

 

对于class类的对象,只有由相同的类加载器加载,并且类名相同,才是相同的class

同时,对于类的委托加载机制,可以遵循,也可以不遵循。

 

定义Hello类。

package com.test.javatechnology.classloader.test;

//位于test目录中。

public class Hello {

}

 

 

定义类加载器。

/**   

* @Title: SpecialClassLoader.java

* @Package com.test.javatechnology.classloader

* @Description:

* @author http://www.cnblogs.com/coe2coe/

* @date 2017年4月5日 下午10:07:53

* @version V1.0   

*/

package com.test.javatechnology.classloader;

 

import java.io.IOException;

import java.io.InputStream;

 

/**

* @ClassName: SpecialClassLoader

* @Description:

* @author http://www.cnblogs.com/coe2coe/

* @date 2017年4月5日 下午10:07:53

*  

*/

public class SpecialClassLoader extends ClassLoader {

 

//彻底改变加载类的方式,可以不遵循类的委托加载机制。

@Override

public Class<?> loadClass(String name) throws ClassNotFoundException {

        System.out.println("loadClass:" + name);

//Object类由系统自行加载。

    if("java.lang.Object".equals(name)){

     return super.loadClass(name);

    }

    //特殊加载方式。

return specialLoadClass(name);

}

 

/**

 * 加载test目录下的class文件。

 * @param name

 * @return

 */

private Class<?> specialLoadClass(String name)  throws ClassNotFoundException  {

Class<?>  clazz;

String  fullname = "test/" + name+".class";

System.out.println("specialLoadClass:"+fullname);

clazz = this.loadClassFromFile(fullname);

System.out.println("---resolveClass--");

super.resolveClass(clazz);

return clazz;

}

 

/**

 * 从文件名加载class文件。

 * @param name class文件名

 * @return

 * @throws ClassNotFoundException

 */

private Class<?> loadClassFromFile(String name) throws ClassNotFoundException{

InputStream is = null;

Class clazz = null;

byte[] bytes = null;

 

try{

//读取class文件的内容。

is = SpecialClassLoader.class.getResourceAsStream(name);

int size = is.available();

bytes = new byte[size];

is.read(bytes);

 

//定义类。

    clazz = super.defineClass(bytes, 0, size);

}catch(Exception e){

e.printStackTrace();

throw new ClassNotFoundException(name);

}finally{

if(is!=null){

try {

is.close();

is = null;

} catch (IOException e) {

e.printStackTrace();

}

}

if(bytes!=null){

bytes = null;

}

}

return clazz;

}

 

 

}

 

 

 

编写测试代码。

public static void main(String[] args) {

 

Class  clazz = null;

ClassLoader classLoader;

 

 

try {

classLoader =  new SpecialClassLoader ();

clazz = classLoader.loadClass("Hello");

 

System.out.println(clazz);

System.out.println(clazz.getClassLoader());

 

 

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

 

Class helloClazz;

helloClazz = Hello.class;

System.out.println("helloClazz:" + helloClazz);

System.out.println(helloClazz.getClassLoader());

System.out.println(helloClazz == clazz);

System.out.println(helloClazz.equals(clazz));

 

}

 

 

 

运行结果:

loadClass:Hello

specialLoadClass:test/Hello.class

loadClass:java.lang.Object

---resolveClass--

class com.test.javatechnology.classloader.test.Hello

com.test.javatechnology.classloader.SpecialClassLoader@106d69c

helloClazz:class com.test.javatechnology.classloader.test.Hello

sun.misc.Launcher$AppClassLoader@e2f2a

false

false

 

Java重要技术(30)类加载器之Class类型的相等比较