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

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

作者: 言西枣 | 来源:发表于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了,那么这个异常都会在这个类初始化的时候被加载,如果不初始化这个类,那么异常也不会被加载。

相关文章

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

    情况:在使用Class.forName进行动态加载类的时候,默认对类进行了初始化, 然后初始化的过程抛出了一个异常...

  • 类的初始化时机

    从语法角度来讲程序可以在两个地方对类进行初始化---定义类变量时指定初始值。---静态初始化块中对类进行初始化。 ...

  • java 一日俩坑11

    今天开发繁忙,抽空看了匿名类 学习神奇的双括号初始化。 后面的代理又是一个坑。 (ㆁωㆁ*)

  • 结构体

    这是struct跟类不同的地方,结构体可以自动初始化器,类是不行的,类在初始化的时候,是不会自动出现x,y,b这些...

  • Jvm学习笔记(三)

    类的初始化和加载 类初始化 遇到new,或读取、修改或调用一个类的static变量时。 反射调用。 初始化一个类时...

  • 类的初始化和实例初始化

    类初始化过程 一个类要创建实例需要先加载并初始化该类main方法所在的类需要先加载和初始化 一个子类要初始化需要先...

  • 接口初始化规则

    在我们初始化一个类的时候,会先初始化它的父类,但是对于接口不是这样的,在初始化一个类时,并不会先初始化它所实现的接...

  • Java类及对象的初始化顺序

    1.初始化规则: 下面规则优先级从前往后依次降低0.加载一个类时先初始化基类后初始化扩展类;1.类的初始化高于对象...

  • Swift-学习笔记--初始化

    初始化 类、结构体、枚举都可以定义初始化器 类有2中初始化器:指定初始化器、便捷初始化器 每个类至少有一个指定初始...

  • Java类加载-初始化顺序

    一个java类初始化的地方可以包括静态代码块、构造代码块、构造函数,则初始化顺序是如何的呢,为什么是这个顺序? 这...

网友评论

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

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