直接說結(jié)論:可以,但是不安全(可能性其實(shí)很小)
原因是 classpath下的類通常是由AppClassLoader加載的, 如果有另外一個(gè)繼承自ExtClassLoader的類加載器也加載了這些.class文件.那么class對(duì)象無論是hash也好,對(duì)象引用值也罷.都是不同的. 即: 他們會(huì)在方法區(qū)形成兩個(gè)類對(duì)象.
還有一種可能是: 使用了繼承自AppClassLoader的兩個(gè)不同的類加載器,分別通過 findClass方法而非loadClass方法進(jìn)行類加載.(loadClass會(huì)優(yōu)先委派雙親,如果雙親==null才會(huì)調(diào)用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進(jìn)行測(cè)試
/**
* @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 是我們這個(gè)類的全路徑
* @return
* @throws ClassNotFoundException
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class log = null;
// 獲取該class文件字節(jié)碼數(shù)組
byte[] classData = getData();
if (classData != null) {
// 將class的字節(jié)碼數(shù)組轉(zhuǎn)換成Class類的實(shí)例
log = defineClass(name, classData, 0, classData.length);
}
return log;
}
/**
* 將class文件轉(zhuǎn)化為字節(jié)碼數(shù)組
* @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可以使用同樣代碼.
結(jié)果:

2020-03-16 18-12-12 的屏幕截圖.png