中午吃饭讨论到了增量打不上的问题。
这样子的情况:
你修改了A类,编译成Jar包,把jar包名称、A.class、路径发给实施地测试验证,实施地按要求操作了,重启服务后,发现增量没打上啊,拿服务端日志一看,还是原来的情况。
于是怀疑实施地没根据这个jar包名称和路径替换class文件,要实施地的把打好增量的jar包发过来,反编译一看,是这个class文件啊,增量打进去了啊。
为什么?难道是正式库和测试库搞混了?...
然后波哥说到一种情况,你修改了A类,是B类调用A类的东西,那么编译之后,把B.class文件发过去就行了。
的确有这种情况。
事实是怎样子的呢?看一个例子(来自于秦小波老师的书)
public class Constant{
//定义一个常量
public final static int MAX_AGE = 150;
};
public class TestClient{
public static void main(String[] args){
System.out.println("人类极限寿命是:" + Constant.MAX_AGE);
}
};
分别javac编译java执行一下,输出的是150.
然后修改常量类,把150改成200。改完后,重新编译常量类javac Constant.java,因为TestClient没修改,所以直接执行java TestClient.
结果是:输出的还是150.
为什么?因为java对于final修饰的基本类型和String类型,编译器会认为它是稳定态,所以在编译的时候就直接编译到字节码中了,避免在运行期间引用,以提高代码的执行效率。
所以,这个测试的Demo说明的就是这种情况,虽然TestClient没有修改,但是也要重新编译一下,再执行,才会出正确的结果200.
那么这种情况在eclipse中是不会出现的,因为在eclipse中,修改了Constant类,eclipse会自动编译所有引用类。
再回到打增量的问题,我们是怎么做的呢?修改了常量类中的final String XXX_SQL,修改了之后,的确是用eclipse把整个工程编译了,可是发给实施地的却是这一个常量类class文件,
那么实施地的引用这个常量类的class还是原来的class。。。问题显而易见。
所以,这种情况的增量打不上,解决办法:修改了的final修饰的基本类型和String类型的常量,被哪些类引用了,把那些类也编译好了一起发过去。
回到波哥说的那种情况,那就是若是只修改了常量,那直接发引用的类就行了,常量类不发也可以。