先看一个实例
使用URLClassLoader每隔3秒钟重复加载A类的class
假如在这3秒钟内我们把class修改了
将会得到什么样的结果:
-------------------------------------
package jvm;
import java.net.URL;
import java.net.URLClassLoader;
public class Test {
public static void main(String[] args) {
while (true) {
try {
ClassLoader parentLoader = Test.class.getClassLoader();
URLClassLoader loader1 = new URLClassLoader(new URL[] { null }, parentLoader);
Class<?> cls1 = loader1.loadClass("jvm.A");
A excel = (A) cls1.newInstance();
excel.print();
Thread.sleep(1000 * 3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package jvm;
public class A {
private String className = "class A";//修改成员变量 class A
static {
System.out.println(" static block initialization ");//修改静态成员变量的打印内容 static block initialization change
}
// private String addField = "field 1";//运行时添加一个成员变量
public void print() {
System.out.println("hello ");//修改方法内的打印内容hello change
System.out.println("------------------" + className);
System.out.println("the end");
}
//运行时添加一个成员方法
// public void print2() {
// System.out.println("hello ");//修改方法内的打印内容hello change
// System.out.println("------------------" + className);
// System.out.println("the end");
// }
}
以debug的方式运行、按照下面的修改后运行得到的结果
--------------------------------
1、修改成员变量的值------------动态打印修改后的值
2、修改成员方法的打印内容-------动态打印修改后的值
3、添加成员变量-----------提示警告
4、添加成员方法-----------提示警告
5、删除成员变量-----------提示警告
6、删除成员方法-----------提示警告
根据以上运行结果
class类加载到虚拟机之后无法添加或者删除成员变量及成员方法
但是可以修改成员变量的值或者修改成员方法中的内容
从另一个角度分析
从JVM结构的角度分析,class的结构信息存放在java的方法区内(method Area).包括常量池、字段描述、方法描述等等
常量池:用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池。
字段信息和方法描述:在编译时期就已经载入到方法区中。运行时无法对该部分的内容进行修改
方法区可以选择不实现垃圾收集、开源的JVM默认是不实现垃圾收集。
方法区是否需要实现垃圾收集其实是一个很难取舍的问题:
假如对方法区的内存进行垃圾收集、可以想象下次再实例化对象需要重新加载class信息无疑是加重了实例化对象的负担
假如不对方法区的内存进行垃圾收集、则无法动态修改一个class的结构;只能修改一些成员变量、成员方法的内容
相对一些热部署的应用将无法实现
分享到:
相关推荐
我一个class类图的例子
一个动态加载android 的class框架, 过程是先解压一个完全的apk,然后创建自己的dexclassloader,然后动态加载指定的activity的过程
wechat.class.php 微信例子wechat.class.php 微信例子wechat.class.php 微信例子
一个计算机的class的层次结构 是一个C++入门级的程序设计 大家是一个很好的程序 初学者可以学学
动态编译字符串成java,并且添加class到jvm
需要framework.jar包。调用方法:Intent intent =new Intent(this,MyService.class); intent.putExtra("package",packet.getPackagename()); startService(intent);
ASM操作字节码,动态生成Java类class文件,模拟Spring的AOP实现原理。
尺寸单位: rpx(responsive pixel): 可以根据...框架组件上支持使用 style、class 属性来控制组件的样式。 style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式
NULL 博文链接:https://name327.iteye.com/blog/1554558
NULL 博文链接:https://zheng12tian.iteye.com/blog/1488813
总共有4个例子: 1.http://127.0.0.1:8080/flexDemo/HelloWorld/HelloWorld.html 2.http://127.0.0.1:8080/flexDemo/HelloWorld/ReadList.html 3.http://127.0.0.1:8080/flexDemo/HelloWorld/ReadExample.html 4....
jquery-scrollAddclass是一款可以在页面滚动时为元素动态添加class类的jquery插件。你可以定制自己的class类,使元素在进入视口时产生指定的动画效果。
可以动态修改CLASS文件,但是修改后的CLASS文件无法反编译,是一个郁闷的事情,但是这个咚咚还是很好用 提供的只是jar包,没有demo,下载的朋友请注意了!! 只是为了提供jar包下载的方便
hibernate Table per class hierarchy 例子代码 hi.baidu.com/zhaochengming
定义一个基类BaseClass,从它派生出类DerivedClass。BaseClass有成员函数fn1(),fn2(),DerivedClass也有成员函数fn1(),fn2()。在主函数中声明一个DerivedClass的对象,分别用DerivedClass的对象以及BaseClass和...
这是微软给的类似于SDK中事例代码的程序,总共101个,这是Base Class Library篇,总共四个。
让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。 3. 自定义URLClassLoader。检查实现类.class文件的修改时间,如果是更新的....
NULL 博文链接:https://ldbjakyo.iteye.com/blog/1046984
采用SetupDi函数集,实现USB设备的动态卸载、动态加载、枚举信息。