看这样的一个场景,某天你正在深夜做系统的上线升级,碰到一个问题,是由基础部门提供的某个jar包里的某个类的bug引起,可能只是某行代码有点问题,而此刻也联系不上相关的同学来修改,怎么办呢?
一种临时的解决办法,在你运行的工程里直接建一个临时的类,与jar包中的类必须具有相同的限定名,在自己的类当中修改该问题。
为什么可以这么做呢?这与类的加载顺序有关,就近加载(此处不讨论类加载器相关问题)。
一、主工程与jar中的类具有相同的限定名
优先加载主工程里的class(注意,这里不讨论jdk相关的类),则此时生效的就是自己定义的class。
二、两个jar中的类具有相同的限定名
按照jar包的加载顺序,一般没啥特殊情况就是按照jar文件的排序来加载,比如a.jar-->b.jar。
其实这里很好理解,想象一下使用JAVA的文件File.listFiles(底层依赖具体平台),在自己不二次排序的情形下,读取到的文件必然是有顺序的,jar包的加载其实也是类似。
三、jar包中class的常量能不能也这么玩
现在jar包中的一个class有一个常量被其它的class引用,我建一个同名的class,并修改常量的值,能不能起作用?这个问题需要分两个情况来看。
1.如果引用该常量的class在外部的jar包中,那么这种情况不会生效了;
2.如果引用该常量的class是自己本工程的class,则会生效。
原因:JAVA的常量传播优化,引入常量的类在编译期已经将常量的值写入自己的常量池当中。
如下图所示,在Test.java文件中引入Kryo类的NOT_NULL常量,当编译成.class文件后,可以看到,根本不存在Kryo这个class的引入信息,直接变成了输出1。
总结:办法虽然方便,可也不能常用,临时的解决办法只能解决一时的问题,最终还是需要解决jar里的问题。(各位老哥觉得有用的话麻烦给小弟点个关注)