`
unbounder
  • 浏览: 174738 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

复习笔记2

    博客分类:
  • job
阅读更多
今天被问及classloader,之前对于这个确实不够了解,貌似写as代码用这个倒是很多,tomcat的时候见过,仅此而已。晚上回来看了下,有了基本的了解。

    public static void main(String[] args) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException {

        Class a = Class.forName("test1.test2");
        a = test2.class;
        a.newInstance();
        test2 b = new test2();
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        a = cl.loadClass("test1.test2");
    }
    
}

class test2 {
    static {
        System.out.println("111");
    }

    public test2() {
        System.out.println("222");
    }
}

简单代码吧,输出为111,222,222
注意的是无论test2.class还是classloader都只是加载class,而不会初始化,也不会调用静态方法。而class.forname这个会调用静态方法。


关于classloader,最基本的了解这是lang下面的一个抽象类,具体实现的有urlclassloader。如果自己实现一个classloader,最重要的实现findClass方法。


一个非常简单的例子。
public class LoaderStudy extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // TODO Auto-generated method stub
        byte[] bytes = loadClassData(name);
        Class theClass = defineClass(name, bytes, 0, bytes.length);// A
        if (theClass == null)
            throw new ClassFormatError();
        return theClass;
    }

    private byte[] loadClassData(String name) {
        // load the class data from the connection
        try {
            String classFile = name;
            FileInputStream fis = new FileInputStream(classFile);
            FileChannel fileC = fis.getChannel();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            WritableByteChannel outC = Channels.newChannel(baos);
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            while (true) {
                int i = fileC.read(buffer);
                if (i == 0 || i == -1) {
                    break;
                }
                buffer.flip();
                outC.write(buffer);
                buffer.clear();
            }
            fis.close();
            return baos.toByteArray();
        } catch (IOException fnfe) {
            try {
                throw new ClassNotFoundException(name);

            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return null;
            }
        }

    }
}

当然,这些classloader都属于User Custom ClassLoader
查阅这篇文章http://www.iteye.com/topic/136427
引用


jvm classLoader architecture :

a, Bootstrap ClassLoader/启动类加载器
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作.



b, Extension ClassLoader/扩展类加载器
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作



c, System ClassLoader/系统类加载器
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作.



b, User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性.



加载顺序为从下向上询问是否加载,然后从上向下加载。

classloader最大的用处肯定是动态加载,类似于play!这样的不需要重启动的热加载可以用classloader来实现。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics