I was looking at the Java virtual machine recently, and the class loader section gave this example:
/**
*类加载器与instanceof关键字演示
**
@author zzm
*/
public class ClassLoaderTest{
public static void main(String[]args) throws Exception{
ClassLoader myLoader=new ClassLoader(){
@Override
public Class<?>loadClass(String name)throws ClassNotFoundException{
try{
String fileName=name.substring(name.lastIndexOf(".")+1)+".class";
InputStream is=getClass().getResourceAsStream(fileName);
if(is==null){
return super.loadClass(name);
}
byte[]b=new byte[is.available()];
is.read(b);
return defineClass(name,b,0,b.length);
}
catch(IOException e){
throw new ClassNotFoundException(name);
}
}
}
;
Object obj=myLoader.loadClass("org.fenixsoft.classloading.ClassLoaderTest").newInstance();
System.out.println(obj.getClass());
System.out.println(obj instanceof org.fenixsoft.classloading.ClassLoaderTest);//false
}
}
In short, use a custom class loader to load a class. The returned class is different from the class loaded by the SystemClassLoader that comes with the jvm.
Then if you use a class that inherits from ClasserLoader, it stands to reason that it will have the same effect
package jvm;
public class MyClassLoader extends ClassLoader{
@Override
public Class<?> loadClass(String fullClassName) throws ClassNotFoundException{
try {
String fileName = fullClassName.substring(fullClassName.lastIndexOf(".")+1,fullClassName.length())+".class";
InputStream is = getResourceAsStream(fileName);
if(is==null){
return super.loadClass(fullClassName);
}
byte[] bytes = new byte[is.available()];
is.read(bytes);
return defineClass(fullClassName,bytes,0,bytes.length);
}catch (Exception e){
throw new ClassNotFoundException();
}
}
public static void main(String[] args) throws Exception{
ClassLoader myClassLoader = new MyClassLoader();
/**
ClassLoader myClassLoader = new ClassLoader() {
@Override
public Class<?> loadClass(String fullClassName) throws ClassNotFoundException {
try {
String fileName = fullClassName.substring(fullClassName.lastIndexOf(".")+1,fullClassName.length())+".class";
InputStream is = getClass().getResourceAsStream(fileName);
if(is==null){
return super.loadClass(fullClassName);
}
byte[] bytes = new byte[is.available()];
is.read(bytes);
return defineClass(fullClassName,bytes,0,bytes.length);
}catch (Exception e){
throw new ClassNotFoundException();
}
}
};
/**/
ClassLoader systemClassLoader = java.lang.ClassLoader.getSystemClassLoader();
Class myClass = myClassLoader.loadClass("jvm.MyClassLoader");
Class systemClass = systemClassLoader.loadClass("jvm.MyClassLoader");
Object myObj = myClass.newInstance();
Object systemObj = systemClass.newInstance();
System.out.println(myClass.equals(systemClass));//true
System.out.println(myObj.getClass().equals(systemObj.getClass()));//true
}
}
The code in the comment is the inheritance of the anonymous inner class. Notice that myClass and systemClass are completely equal, but myClass is generated using the class MyClassLoader that inherits from ClassLoader. Why is this? . .
The second code goes to
Loading
class
文件用getClass().getResourceAsStream