通常我们会比较基本类型、引用类型、数组等是否相等,很少会 比较对象的Class实例对象是否相等,那么class实例对象如何比较相等呢?

  • 可以使用“==”比较是否相等
obj.getClass() == ClassEqualTest.class
  • 可以使用equals比较是否相等
obj.getClass().equals(ClassEqualTest.class)
  • 同一个classloader加载两个类使用“==”或equals做比较是正确的;
  • 两个不同的classloader分别加载两个类做比较就会有问题,两个实例不会相等;
  • 自定义类加载器
package reflect;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader{

    private String rootPath;

    public MyClassLoader(String rootPath){
        this.rootPath = rootPath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //check if the class have been loaded
        Class<?> c = findLoadedClass(name);        
        if(c!=null){
            return c;
        }
        //load the class
        byte[] classData = getClassData(name);
        if(classData==null){
            throw new ClassNotFoundException();
        }
        else{
            c = defineClass(name,classData, 0, classData.length);
            return c;
        }    
    }

    private byte[] getClassData(String className){
        String path = rootPath+"/"+className.replace('.', '/')+".class";

        InputStream is = null;
        ByteArrayOutputStream bos = null;
        try {
            is = new FileInputStream(path);
            bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int temp = 0;
            while((temp = is.read(buffer))!=-1){
                bos.write(buffer,0,temp);
            }
            return bos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                is.close();
                bos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }            
        }

        return null;        
    }    

}
  • 在根目录创建一个测试类HelloWorld.java,编译出class文件,并将文件放到D盘根目录下
package reflect;

public class ClassEqualTest {

    public static void main(String[] args) throws Exception {
        ClassEqualTest obj = new ClassEqualTest();
        /**
         * 使用相同的类加载器
         */
        System.out.println(obj.getClass() == ClassEqualTest.class);
        System.out.println(obj.getClass().equals(ClassEqualTest.class));
        //通过自定义类加载器获得类的Class文件
        Class<?> clazz = new MyClassLoader("D:").loadClass("HelloWorld");
        //当前类加载器和自定义类加载器生成的class对象做比较返回false
        System.out.println(clazz == obj.getClass());
    }
}