Maison  >  Questions et réponses  >  le corps du texte

java - Classes internes anonymes et classes héritées, pourquoi y a-t-il une différence lors de l'implémentation de ClassLoader

Je regardais récemment la machine virtuelle Java, et la section du chargeur de classe a donné cet exemple :

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

En bref, utilisez un chargeur de classe personnalisé pour charger une classe. La classe renvoyée est différente de la classe chargée par le SystemClassLoader fourni avec le jvm.

Ensuite, si vous utilisez une classe qui hérite de ClasserLoader, il va de soi qu'elle aura le même effet

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

    }
}

Le code dans le commentaire est l'héritage de la classe interne anonyme. Notez que myClass et systemClass sont complètement égaux, mais myClass est généré à l'aide de la classe MyClassLoader qui hérite de ClassLoader. Pourquoi ? . .

PHP中文网PHP中文网2682 Il y a quelques jours708

répondre à tous(1)je répondrai

  • 巴扎黑

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

    Le deuxième code va à

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

    Chargementclass文件用getClass().getResourceAsStream

    répondre
    0
  • Annulerrépondre