Ich habe Zweifel mit Klasse ‚s identifizieren, Klasse‘ s sollte The same classloader instance
+ The same class full path
.Aber ich einige Testfälle machen sein identifizieren, funktioniert es nicht.Java-Klasse identifizieren Classloader
Ich habe ein selbstdefinierte Classloader:
import java.io.*;
public class FileSystemClassLoader extends ClassLoader {
private String rootDir;
public FileSystemClassLoader(String rootDir) {
this.rootDir = rootDir;
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = getClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
} else {
return defineClass(name, classData, 0, classData.length);
}
}
private byte[] getClassData(String className) {
String path = classNameToPath(className);
try {
InputStream ins = new FileInputStream(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesNumRead = 0;
while ((bytesNumRead = ins.read(buffer)) != -1) {
baos.write(buffer, 0, bytesNumRead);
}
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String classNameToPath(String className) {
return rootDir + File.separatorChar
+ className.replace('.', File.separatorChar) + ".class";
}
}
Die Sample
Klasse:
public class Sample {
private Sample instance;
public void setSample(Object instance) {
this.instance = (Sample) instance;
}
}
Und ein Testfall:
String classDataRootPath = "/Users/haolin/Github/jvm/target/classes";
FileSystemClassLoader fscl1 = new FileSystemClassLoader(classDataRootPath);
FileSystemClassLoader fscl2 = new FileSystemClassLoader(classDataRootPath);
String className = "me.hao0.jvm.classloader.Sample";
try {
Class<?> class1 = fscl1.loadClass(className);
Object obj1 = class1.newInstance();
Class<?> class2 = fscl2.loadClass(className);
Object obj2 = class2.newInstance();
Method setSampleMethod = class1.getMethod("setSample", Object.class);
setSampleMethod.invoke(obj1, obj2);
} catch (Exception e) {
e.printStackTrace();
}
Es sollte ClassCastException
auftreten, wenn setSampleMethod.invoke(obj1, obj2)
, weil obj1 und obj2 sind verschiedene Klasse (ihre Classloader anders ist), aber der Code funktioniert gut, wirft keine ClassCastException
Kann jemand das vorschlagen?
Sie sind wiederum die gleiche Klasse, obwohl richtig? Ich sehe keinen Unterschied zwischen den beiden. – 3kings
Ja, auch ** obj1 ** und ** obj2 ** sind die gleiche vollständige Pfadklasse 'Sample', aber die Klassenladeprogramme laden ihre Klasse' Sample' sind unterschiedlich, 'obj1' ist' fscl1', 'obj2' ist' fscl2', also sollte 'jvm' ihre Klasse anders sehen, tat es aber nicht. – haolin
Was ist 'class1 == class2' in Ihrem Test? –