美文网首页
记类初始化一个神奇的地方

记类初始化一个神奇的地方

作者: 言西枣 | 来源:发表于2018-05-31 15:23 被阅读11次

    情况:
    在使用Class.forName进行动态加载类的时候,默认对类进行了初始化,

    Class.forName("org.reflections.serializers.XmlSerializer");
    

    然后初始化的过程抛出了一个异常如下:

    Exception in thread "main" java.lang.NoClassDefFoundError: org/dom4j/DocumentException
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at jdk.load.Debug.main(Debug.java:16)
    Caused by: java.lang.ClassNotFoundException: org.dom4j.DocumentException
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 3 more
    

    虽然说类路径下确实没有dom4j的包,但是去看了一下类的源码,并没有任何的类初始化代码,也只有一个方法里抛出了DocumentException这个异常,那么为什么初始化XmlSerializer会加载这个类呢

    public class XmlSerializer implements Serializer {
    
        public Reflections read(InputStream inputStream) {
            Reflections reflections;
            try {
                Constructor<Reflections> constructor = Reflections.class.getDeclaredConstructor();
                constructor.setAccessible(true);
                reflections = constructor.newInstance();
            } catch (Exception e) {
                reflections = new Reflections(new ConfigurationBuilder());
            }
    
            try {
                Document document = new SAXReader().read(inputStream);
                for (Object e1 : document.getRootElement().elements()) {
                    Element index = (Element) e1;
                    for (Object e2 : index.elements()) {
                        Element entry = (Element) e2;
                        Element key = entry.element("key");
                        Element values = entry.element("values");
                        for (Object o3 : values.elements()) {
                            Element value = (Element) o3;
                            reflections.getStore().getOrCreate(index.getName()).put(key.getText(), value.getText());
                        }
                    }
                }
            } catch (DocumentException e) {
                throw new ReflectionsException("could not read.", e);
            } catch (Throwable e) {
                throw new RuntimeException("Could not read. Make sure relevant dependencies exist on classpath.", e);
            }
    
            return reflections;
        }
    }
    

    于是自己写了一小段代码,TestClass只包括了一个抛出这个异常的方法,进行试验,发现初始化类的时候,确实加载了这个异常类:



    在方法中去掉catch语句之后,就不会加载这个类了。

    总结一下:类中的方法抛出了checked异常之后,无论是throws或者catch了,那么这个异常都会在这个类初始化的时候被加载,如果不初始化这个类,那么异常也不会被加载。

    相关文章

      网友评论

          本文标题:记类初始化一个神奇的地方

          本文链接:https://www.haomeiwen.com/subject/dnpqsftx.html