说我有一个名为NameGenerator的类.我可以使用它来根据给定的逻辑生成名称.然后我用一个方法来编写一个TestNameGeneration类,该方法要求用户输入一个字母,并根据该名称生成一个名称.现在我想更改NameGeneration类中的逻辑,并应用该特定的更改而不停止应用程序.
我这样做是为了更多的了解类加载器,有人可以解释我必须学习的关键概念,以便做这样的或网站的任何参考?
解决方法
这是一个工作测试.每5秒Test.main()从文件系统重新加载test.Test1.class并调用Test1.hello()
package test; public class Test1 { public void hello() { System.out.println("Hello !"); } } public class Test { static class TestClassLoader extends ClassLoader { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { if (name.equals("test.Test1")) { try { InputStream is = Test.class.getClassLoader().getResourceAsstream("test/Test1.class"); byte[] buf = new byte[10000]; int len = is.read(buf); return defineClass(name,buf,len); } catch (IOException e) { throw new ClassNotFoundException("",e); } } return getParent().loadClass(name); } } public static void main(String[] args) throws Exception { for (;;) { Class cls = new TestClassLoader().loadClass("test.Test1"); Object obj = cls.newInstance(); cls.getmethod("hello").invoke(obj); Thread.sleep(5000); } } }
运行.然后更改并重新编译Test1
System.out.println("Hello !!!");
而测试正在运行.您将看到Test1.hello输出更改
... Hello ! Hello ! Hello !!! Hello !!!
这就是Tomcat如何重新加载webapps.它为每个webapp都有一个单独的ClassLoader,并在新的ClassLoader中加载一个新版本.旧的是GCed就像任何Java对象以及旧类一样.
请注意,我们使用TestClassLoader加载Test1,并通过反射调用其第一个方法.但是所有Test1依赖项将被隐式加载Test1类加载器,即所有Test1应用程序将被JVM加载到TestClassLoader中.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。