java - Anonyme innere Klassen und geerbte Klassen. Warum gibt es einen Unterschied bei der Implementierung von ClassLoader?
PHP中文网
PHP中文网 2017-05-17 10:07:45
0
1
767

Ich habe mir kürzlich die Java Virtual Machine angesehen und im Abschnitt zum Klassenlader gab es dieses Beispiel:

/**
*类加载器与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
    }
}

Kurz gesagt, verwenden Sie einen benutzerdefinierten Klassenlader, um eine Klasse zu laden. Die zurückgegebene Klasse unterscheidet sich von der Klasse, die vom SystemClassLoader geladen wird, der mit der JVM geliefert wird.

Wenn Sie dann eine Klasse verwenden, die von ClasserLoader erbt, liegt es nahe, dass sie den gleichen Effekt hat

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

    }
}

Der Code im Kommentar ist die Vererbung der anonymen inneren Klasse. Beachten Sie, dass myClass und systemClass völlig gleich sind, myClass jedoch mithilfe der Klasse MyClassLoader generiert wird, die von ClassLoader erbt. . .

PHP中文网
PHP中文网

认证0级讲师

Antworte allen(1)
巴扎黑

第二个代码走到

if(is==null){
    return super.loadClass(fullClassName);
}

加载class文件用getClass().getResourceAsStream

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage