java - Classes internes anonymes et classes héritées, pourquoi y a-t-il une différence lors de l'implémentation de ClassLoader
PHP中文网
PHP中文网 2017-05-17 10:07:45
0
1
774

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中文网

认证0级讲师

répondre à tous(1)
巴扎黑

Le deuxième code va à

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

Chargementclass文件用getClass().getResourceAsStream

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal