suchen

Heim  >  Fragen und Antworten  >  Hauptteil

java - Anonyme innere Klassen und geerbte Klassen. Warum gibt es einen Unterschied bei der Implementierung von ClassLoader?

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中文网2748 Tage vor769

Antworte allen(1)Ich werde antworten

  • 巴扎黑

    巴扎黑2017-05-17 10:09:45

    第二个代码走到

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

    加载class文件用getClass().getResourceAsStream

    Antwort
    0
  • StornierenAntwort