zoukankan      html  css  js  c++  java
  • java类加载器的一些测试

    package classloader;
    
    import java.lang.reflect.Method;
    
    import org.junit.Test;
    
    import com.example.Sample;
    
    
    public class ClassIdentity {
    
        public static void main(String[] args) {
            
    //        new ClassIdentity().testClassIdentity();
    //        System.out.println("执行了吗");
            
            new ClassIdentity().testICalculator();
        }
        
        public void testICalculator(){
            
            String basicClassName = "com.example.CalculatorBasic";
            String advancedClassName = "com.example.CalculatorAdvanced";
            String classDataRootPath = "C:\";
            FileSystemClassLoader fscl1 = new FileSystemClassLoader(classDataRootPath);
            
            try {
                Class<?> class1 = fscl1.loadClass(basicClassName);
                //下面这句会导致fscl1尝试加载在C:下面加载classloader.ICalculator
                ICalculator calculator=(ICalculator)class1.newInstance();
                System.out.println(calculator.getVersion());
                System.out.println( ICalculator.class.getClassLoader());
                System.out.println( calculator.getClass().getClassLoader());
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            
        }
        @Test
        public void testClassIdentity() {
            String classDataRootPath = "C:\";
            FileSystemClassLoader fscl1 = new FileSystemClassLoader(classDataRootPath);
            FileSystemClassLoader fscl2 = new FileSystemClassLoader(classDataRootPath);
            String className = "com.example.Sample";    
            try {
                Class<?> class1 = fscl1.loadClass(className);
                Object obj1 = class1.newInstance();
    
                Class<?> class2 = fscl2.loadClass(className);
                Object obj2 = class2.newInstance();
                
                System.out.println("不同加载器->" + class1.equals(class2));
                
                Class<?> c1=  this.getClass().getClassLoader().loadClass("classloader.Versioned");
                Class<?> c2=  this.getClass().getClassLoader().loadClass("classloader.Versioned");
                
                System.out.println("同一个->" + c1.equals(c2));
                
                Method setSampleMethod = class1.getMethod("setSample", java.lang.Object.class);
    //            setSampleMethod.invoke(obj1, obj1);
    //            setSampleMethod.invoke(obj1, obj1);
                System.out.println( Sample.class.getClassLoader());
                System.out.println( ClassIdentity.class.getClassLoader());
                System.out.println(obj1.getClass().getClassLoader() );
                Sample sample=(Sample)obj1; //无法将obj1转化成Sample,引用的类加载器不同
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }
    View Code

    testICalculator()输出:
    这里com.example.CalculatorBasic
    这里classloader.ICalculator
    这里java.lang.Object
    1.0
    sun.misc.Launcher$AppClassLoader@105d88a
    classloader.FileSystemClassLoader@76fba0

    改写类加载器

    package classloader;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    public class FileSystemClassLoader extends ClassLoader {
    
        private String rootDir;
    
        public FileSystemClassLoader(String rootDir) {
            this.rootDir = rootDir;
        }
     
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            byte[] classData = getClassData(name);
            if (classData == null) {
                throw new ClassNotFoundException();
            }
            else {
                return defineClass(name, classData, 0, classData.length);
            }
        }
    
        private byte[] getClassData(String className) {
            String path = classNameToPath(className);
            try {
                InputStream ins = new FileInputStream(path);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int bufferSize = 4096;
                byte[] buffer = new byte[bufferSize];
                int bytesNumRead = 0;
                while ((bytesNumRead = ins.read(buffer)) != -1) {
                    baos.write(buffer, 0, bytesNumRead);
                }
                return baos.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private String classNameToPath(String className) {
            return rootDir + File.separatorChar
                    + className.replace('.', File.separatorChar) + ".class";
        }
        
        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
            System.out.println("这里" + name);
            if("java.lang.Object".equals(name)
               || "classloader.ICalculator".equals(name)        
                    ){
                return super.loadClass(name, resolve);
            }
            
            return findClass(name);
        }
        
    }
    View Code

     
    注释//Sample sample=(Sample)obj1; 后的输出:
    这里com.example.Sample
    这里java.lang.Object
    这里com.example.Sample
    这里java.lang.Object
    不同加载器->false
    同一个->true
    sun.misc.Launcher$AppClassLoader@105d88a
    sun.misc.Launcher$AppClassLoader@105d88a
    classloader.FileSystemClassLoader@1866417

    打开注释后的输出:


    这里com.example.Sample
    这里java.lang.Object
    这里com.example.Sample
    这里java.lang.Object
    不同加载器->false
    同一个->true
    sun.misc.Launcher$AppClassLoader@105d88a
    sun.misc.Launcher$AppClassLoader@105d88a
    classloader.FileSystemClassLoader@1526e3
    java.lang.ClassCastException: com.example.Sample cannot be cast to com.example.Sample

  • 相关阅读:
    Method总结
    使用CSS的五种方式
    debug js code
    Overload
    fiddler模拟弱网测试
    POJ 1753 Flip Game (IDA*)
    UVA 11400 Lighting System Design(照明系统设计)(dp)
    UVA 12563 Jin Ge Jin Qu hao(劲歌金曲)(01背包+滚动数组)
    UVA 116 Unidirectional TSP (单向TSP)(dp多段图的最短路)
    UVA 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)
  • 原文地址:https://www.cnblogs.com/wdfrog/p/3169562.html
Copyright © 2011-2022 走看看