通常我们会比较基本类型、引用类型、数组等是否相等,很少会 比较对象的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());
}
}