Java-A correct behavior custom class loader 左手的ㄟ右手 2022-12-31 03:25 144阅读 0赞 分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击[http://www.captainbed.net][http_www.captainbed.net] It is possible to load and reload classes at runtime in Java, though it is not as straightforward as one might have hoped. This text will explain when and how you can load and reload classes in Java. ## The ClassLoader ## All classes in a Java application are loaded using some subclass of `java.lang.ClassLoader`. Loading classes dynamically must therefore also be done using a `java.lang.ClassLoader` subclass. When a class is loaded, all classes it references are loaded too. This class loading pattern happens recursively, until all classes needed are loaded. This may not be all classes in the application. Unreferenced classes are not loaded until the time they are referenced. ## The ClassLoader Hierarchy ## Class loaders in Java are organized into a hierarchy. When you create a new standard Java `ClassLoader` you must provide it with a parent `ClassLoader`. If a `ClassLoader` is asked to load a class, it will ask its parent class loader to load it. If the parent class loader can't find the class, the child class loader then tries to load it itself. ## Class Loading ## The steps a given class loader uses when loading classes are: 1. Check if the class was already loaded. 2. If not loaded, ask parent class loader to load the class. 3. If parent class loader cannot load class, attempt to load it in this class loader. **When you implement a class loader that is capable of reloading classes you will need to deviate a bit from this sequence. The classes to reload should not be requested loaded by the parent class loader.** More on that later. ## Dynamic Class Loading ## Loading a class dynamically is easy. All you need to do is to obtain a `ClassLoader` and call its `loadClass()` method. Here is an example: public class MainClass { public static void main(String[] args){ ClassLoader classLoader = MainClass.class.getClassLoader(); try { Class myClass = classLoader.loadClass("com.xxx.myClass"); System.out.println("myClass.getName() = " + myClass.getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } ## Dynamic Class Reloading ## Dynamic class reloading is a bit more challenging. Java's builtin Class loaders always checks if a class is already loaded before loading it. Reloading the class is therefore not possible using Java's builtin class loaders. To reload a class you will have to implement your own `ClassLoader` subclass. Even with a custom subclass of `ClassLoader` you have a challenge. Every loaded class needs to be linked. This is done using the `ClassLoader.resolve()` method. This method is final, and thus cannot be overridden in your `ClassLoader` subclass. The `resolve()` method will not allow any given `ClassLoader` instance to link the same class twice. Therefore, everytime you want to reload a class you must use a new instance of your `ClassLoader` subclass. This is not impossible, but necessary to know when designing for class reloading. ## Designing your Code for Class Reloading ## As stated earlier you cannot reload a class using a `ClassLoader` that has already loaded that class once. Therefore you will have to reload the class using a different `ClassLoader` instance. But this poses som new challenges. Every class loaded in a Java application is identified by its fully qualified name (package name + class name), and the `ClassLoader` instance that loaded it. That means, that a class `MyObject` loaded by class loader A, is not the same class as the `MyObject` class loaded with class loader B. Look at this code: MyObject object = (MyObject) myClassReloadingFactory.newInstance("com.xxx.MyObject"); Notice how the `MyObject` class is referenced in the code, as the type of the `object` variable. This causes the `MyObject` class to be loaded by the same class loader that loaded the class this code is residing in. If the `myClassReloadingFactory` object factory reloads the `MyObject` class using a different class loader than the class the above code resides in, you cannot cast the instance of the reloaded `MyObject` class to the `MyObject` type of the `object` variable. Since the two `MyObject` classes were loaded with different class loaders, the are regarded as different classes, even if they have the same fully qualified class name. Trying to cast an object of the one class to a reference of the other will result in a `ClassCastException`. It is possible to work around this limitation but you will have to change your code in either of two ways: 1. Use an interface as the variable type, and just reload the implementing class. 2. Use a superclass as the variable type, and just reload a subclass. Here are two coresponding code examples: MyObjectInterface object = (MyObjectInterface) myClassReloadingFactory.newInstance("com.xxx.MyObject"); MyObjectSuperclass object = (MyObjectSuperclass) myClassReloadingFactory.newInstance("com.xxx.MyObject"); Either of these two methods will work if the type of the variable, the interface or superclass, is not reloaded when the implementing class or subclass is reloaded. To make this work you will of course need to implement your class loader to let the interface or superclass be loaded by its parent. When your class loader is asked to load the `MyObject` class, it will also be asked to load the `MyObjectInterface` class, or the `MyObjectSuperclass` class, since these are referenced from within the `MyObject` class. Your class loader must delegate the loading of those classes to the same class loader that loaded the class containing the interface or superclass typed variables. ## ClassLoader Load / Reload Example ## The text above has contained a lot of talk. Let's look at a simple example. Below is an example of a simple `ClassLoader` subclass. Notice how it delegates class loading to its parent except for the one class it is intended to be able to reload. If the loading of this class is delegated to the parent class loader, it cannot be reloaded later. Remember, a class can only be loaded once by the same `ClassLoader` instance. As said earlier, this is just an example that serves to show you the basics of a `ClassLoader`'s behaviour. It is not a production ready template for your own class loaders. Your own class loaders should probably not be limited to a single class, but a collection of classes that you know you will need to reload. In addition, you should probably not hardcode the class paths either. public class MyClassLoader extends ClassLoader{ public MyClassLoader(ClassLoader parent) { super(parent); } public Class loadClass(String name) throws ClassNotFoundException { if(!"reflection.MyObject".equals(name)){ return super.loadClass(name); } try { String url = "file:C:/yourtargetpath/classes/reflection/MyObject.class"; URL myUrl = new URL(url); URLConnection connection = myUrl.openConnection(); InputStream input = connection.getInputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int data = input.read(); while(data != -1){ buffer.write(data); data = input.read(); } input.close(); byte[] classData = buffer.toByteArray(); return defineClass("reflection.MyObject",classData, 0, classData.length); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } } Below is an example use of the `MyClassLoader`. public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader(); MyClassLoader classLoader = new MyClassLoader(parentClassLoader); Class myObjectClass = classLoader.loadClass("reflection.MyObject"); MyObjectInterface object1 = (MyObjectInterface) myObjectClass.newInstance(); MyObjectSuperClass object2 = (MyObjectSuperClass) myObjectClass.newInstance(); // Create new class loader so classes can be reloaded classLoader = new MyClassLoader(parentClassLoader); myObjectClass = classLoader.loadClass("reflection.MyObject"); object1 = (MyObjectInterface) myObjectClass.newInstance(); object2 = (MyObjectSuperClass) myObjectClass.newInstance(); } Here is the `reflection.MyObject` class that is loaded using the class loader. Notice how it both extends a superclass and implements an interface. This is just for the sake of the example. In your own code you would only have to one of the two - extend or implement. public class MyObject extends MyObjectSuperClass implements MyObjectInterface { // ... body of class ... // override superclass methods // or implement interface methods } [http_www.captainbed.net]: http://www.captainbed.net/troubleshooter
相关 CSS scroll-behavior 当滚动通过导航或者CSSOM滚动API触发时的滚动行为只有两个关键字属性值.autosmooth?注意除了上面两种滚动触发外的任何滚动, 比如用户使用鼠标滚动, 都不会被... àì夳堔傛蜴生んèń/ 2024年05月24日 03:04/ 0 赞/ 72 阅读
相关 class="navbar navbar-custom navbar-fixed-top" role="navigation"> class="co... 这是一段HTML代码,它定义了一个导航栏的布局。其中包含了一个"navbar-header" div块和一个"navbar-brand"链接。这个链接具有"page-scrol 墨蓝/ 2024年03月26日 10:22/ 0 赞/ 48 阅读 相关 corrected(corrected) corrected 章是什么意思 corrected 英 \[ kə'rektɪd \] 美 \[ kə'rektɪd \] 折算的,修正的,校正的 改正 corre 爱被打了一巴掌/ 2023年09月26日 13:13/ 0 赞/ 16 阅读 相关 Java-A correct behavior custom class loader 分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击[http://www.captainbed.net][http_www.cap 左手的ㄟ右手/ 2022年12月31日 03:25/ 0 赞/ 145 阅读 相关 Error Correction Problem E: Error Correction Time Limit: 1 Sec Memory Limit: 64 MB Submit: 14 So 布满荆棘的人生/ 2022年08月01日 02:46/ 0 赞/ 11 阅读 相关 Behavior behavior能实现viewgroup中各个view事件的相互监听。已经实现的behavior有CoordinatorLayout.Behavior/FloatingActi 秒速五厘米/ 2022年06月09日 11:48/ 0 赞/ 228 阅读 相关 【PB】PB中object,control,custom class,custom visual,custom external等概念的区别 pb的5种类: custom class :不可见用户自定义类 ,如实现函数的多态 standard class :标准不可见控件 扩展类 custom visual 绝地灬酷狼/ 2022年06月09日 06:30/ 0 赞/ 363 阅读 相关 Java反射——Class Loader JVM在运行时会产生三个ClassLoader,Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader。 Bo 刺骨的言语ヽ痛彻心扉/ 2022年06月08日 04:38/ 0 赞/ 301 阅读 相关 Android CoordinatorLayout Behavior Behavior是Android Support Design库里面新增的布局概念,主要的作用是用来协调CoordinatorLayout里面直接Child Vi 野性酷女/ 2022年05月29日 04:40/ 0 赞/ 203 阅读 相关 javassist编程指南==Class loader 类加载 Class loader 类加载 如果必须修改的类是预先知道的,最简单的修改类的方式可能是以下这些: 1.通过调用`ClassPool.get()`获取一个`Ct 迈不过友情╰/ 2021年12月04日 03:06/ 0 赞/ 856 阅读
相关 corrected(corrected) corrected 章是什么意思 corrected 英 \[ kə'rektɪd \] 美 \[ kə'rektɪd \] 折算的,修正的,校正的 改正 corre 爱被打了一巴掌/ 2023年09月26日 13:13/ 0 赞/ 16 阅读
相关 Java-A correct behavior custom class loader 分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击[http://www.captainbed.net][http_www.cap 左手的ㄟ右手/ 2022年12月31日 03:25/ 0 赞/ 145 阅读
相关 Error Correction Problem E: Error Correction Time Limit: 1 Sec Memory Limit: 64 MB Submit: 14 So 布满荆棘的人生/ 2022年08月01日 02:46/ 0 赞/ 11 阅读
相关 Behavior behavior能实现viewgroup中各个view事件的相互监听。已经实现的behavior有CoordinatorLayout.Behavior/FloatingActi 秒速五厘米/ 2022年06月09日 11:48/ 0 赞/ 228 阅读
相关 【PB】PB中object,control,custom class,custom visual,custom external等概念的区别 pb的5种类: custom class :不可见用户自定义类 ,如实现函数的多态 standard class :标准不可见控件 扩展类 custom visual 绝地灬酷狼/ 2022年06月09日 06:30/ 0 赞/ 363 阅读
相关 Java反射——Class Loader JVM在运行时会产生三个ClassLoader,Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader。 Bo 刺骨的言语ヽ痛彻心扉/ 2022年06月08日 04:38/ 0 赞/ 301 阅读
相关 Android CoordinatorLayout Behavior Behavior是Android Support Design库里面新增的布局概念,主要的作用是用来协调CoordinatorLayout里面直接Child Vi 野性酷女/ 2022年05月29日 04:40/ 0 赞/ 203 阅读
相关 javassist编程指南==Class loader 类加载 Class loader 类加载 如果必须修改的类是预先知道的,最简单的修改类的方式可能是以下这些: 1.通过调用`ClassPool.get()`获取一个`Ct 迈不过友情╰/ 2021年12月04日 03:06/ 0 赞/ 856 阅读
还没有评论,来说两句吧...