ClassLoader in Java
我正在使用Java中的类加载器,发现以下行为。我可以从逻辑上对此进行推理,但是我不确定我所假设的是完全正确的。我想知道这种行为的更正式解释。
我在想什么?
所以我有以下代码:
1 2 3 4 5 6 | URL[] classURLs = {new URL("file://C:/Users/HP/IdeaProjects/test/out/production/test/")}; URLClassLoader urlClassLoader = new URLClassLoader(classURLs, null); Class< ? > personClass = urlClassLoader.loadClass("com.test.Person"); // the following line will give a ClassCastException Person p = (Person) personClass.getDeclaredConstructor().newInstance(); |
现在,最后一行给了我
我对为什么得到
所以现在我继续以下列方式探索和改变
1 |
这里
我对此的推理(猜测):由于现在
我假设将要类型转换的对象的类的类加载器已与需要类型转换的类的类加载器进行了检查,并且如果该类加载器与对象类的类加载器的父类不匹配,则尝试进行匹配并且这继续。
如果我在任何时候错了,请纠正我,并提供指向此行为的正式文档的指针。
我已经看到了此链接,但这未提供我所要求的详细信息。
您观察到的行为的正式文档在ClassLoader#loadClass()文档中:
Loads the class with the specified binary name. The default implementation of this method searches for classes in the following order:
Invoke findLoadedClass(String) to check if the class has already been loaded.
Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead.
Invoke the findClass(String) method to find the class.
如果指定父类加载器,则
因此,如果您设置父类加载器,则此行:
1 | Class< ? > personClass = urlClassLoader.loadClass("com.test.Person"); |
表现与
1 | Class< ? > personClass = Main.class.getClassLoader().loadClass("com.test.Person"); |
如果类
您正在动态加载类,因此,由于您能够编译类" Person",因此这意味着您将两次加载同一类,从而导致类强制转换异常。
从类路径中删除该库,但是不会收到此错误,您也将失去对Person对象的访问。
当您加载它时它仍然存在,但是访问它的方式将是通过Reflection,并且您必须将" Person"对象存储为" Object"。