JAVA class对象是否能作为比较值
2020-03-16 本文已影响0人
万里凪
直接说结论:可以,但是不安全(可能性其实很小)
原因是 classpath下的类通常是由AppClassLoader加载的, 如果有另外一个继承自ExtClassLoader的类加载器也加载了这些.class文件.那么class对象无论是hash也好,对象引用值也罢.都是不同的. 即: 他们会在方法区形成两个类对象.
还有一种可能是: 使用了继承自AppClassLoader的两个不同的类加载器,分别通过 findClass方法而非loadClass方法进行类加载.(loadClass会优先委派双亲,如果双亲==null才会调用findClass).
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
File filpath = new File("");
String path = "file:"+filpath.getAbsoluteFile()+"/xxx.class";
URL newurl=new URL(path);
TestClassLoader loader1 = new TestClassLoader(newurl.getPath());
TestClassLoader2 loader2 = new TestClassLoader2(newurl.getPath());
Class<?> cls1 = loader1.findClass(CloudUserDAOImpl.class.getCanonicalName());
Class<?> cls2 = loader2.findClass(CloudUserDAOImpl.class.getCanonicalName());
Map result = new HashMap();
// result.put(cls1, cls1);
// result.put(cls2, cls2);
// result.put("equalClass", cls1 == cls2);
result.put("hash1", cls1.hashCode());
result.put("hash2", cls2.hashCode());
System.out.println(result);
}
可以使用自定义的的classloader进行测试
/**
* @author dqy
* @version 1.0
* @date 2020/3/16 下午3:54
*/
public class TestClassLoader extends ClassLoader {
//指定路径
private String path ;
public TestClassLoader(String classPath){
path = classPath;
}
/**
* 重写findClass方法
* @param name 是我们这个类的全路径
* @return
* @throws ClassNotFoundException
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class log = null;
// 获取该class文件字节码数组
byte[] classData = getData();
if (classData != null) {
// 将class的字节码数组转换成Class类的实例
log = defineClass(name, classData, 0, classData.length);
}
return log;
}
/**
* 将class文件转化为字节码数组
* @return
*/
private byte[] getData() {
File file = new File(path);
if (file.exists()){
FileInputStream in = null;
ByteArrayOutputStream out = null;
try {
in = new FileInputStream(file);
out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int size = 0;
while ((size = in.read(buffer)) != -1) {
out.write(buffer, 0, size);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return out.toByteArray();
} else {
return null;
}
}
}
TestClassLoader2可以使用同样代码.
结果:
2020-03-16 18-12-12 的屏幕截图.png