OSGi框架下对共享Jar的常量引用和编译时常量

        前些天,在项目中碰到了一个关于编译时常量问题,一开始丝毫没有头绪,而且觉得百思不得其解时,碰巧又正在看《深入理解Java虚拟机》,才豁然开朗,终于在经过两天时间的痛苦分析中,解决了问题,于是觉得应该记录下来。

        问题:公司的项目是用OSGi框架实现的Android插件开发应用,在考虑到代码冗余和应用包大小问题,会考虑将多个插件共用的开源或者自研的Jar包下沉到基座中打包,插件打包时,只对共享Jar编译,而不打包到插件中;而对于下沉的共用Jar包,会涉及到一些常量和类对象的引用。

基座中原始的共用Jar中的代码:

public class A
{
  public static final String C = "ABC";
}

插件中的代码,类B的常量C引用类Jar中类A的常量C:

public class B
{
  public static final String C = A.C;
}

由于有多个渠道打包,所以共用的Jar在另外一个渠道中修改类部分常量:

public class A
{
  public static final String C = "123";
}

        由于插件中的类B引用类共享Jar中的常量,所以理论上说,插件不需要重新打包,完美适配新的渠道环境运行。但是世纪运行过程中,插件的B.C却一直等于"ABC",而非预期中的"123";一开始我一直怀疑是基座中的共享Jar包打错了,还是用上一个渠道的原始代码打的Jar包,但是经过确认,共享Jar包没有打错;但是经过反复的测试,以及代码排查,没有发现任何的问题,一时之间觉得完全不可能,完全不可思议。

        经过一天多的反复测试和排查没有结果,已经觉得无从下手时,突然想起这前两天看的《深入理解Java虚拟机》中提到的编译时常量的内容,Java代码为了性能更优,在编译时就对代码做了优化,常量在编译时就生成了对应的符号信息,而不会再有对象或者类引用类,这时才豁然开朗。查看了插件打包的共用Jar中的A.class果然是原始代码,A.C = "ABC",也就是说,在编译时B.C = "ABC"是已经确定,不会再修改的,运行时也不会去引用新的Jar包中的A.C,通俗的说,就是编译结束后,A和B就不会存在任何关系。

        解决思路:插件在对不同渠道打包时,要采用不同渠道打出来的共用Jar进行编译打包,配合不同渠道使用不同的插件;经过验证,分析结果和测试结果完全一致;至此,经历两天的不可思议终于引刃而解。

        思考总结:在看《深入理解Java虚拟机》这本书时,一直觉得,这本书对平常开发没什么帮助,但是对于以后的技术提升还是有帮助的;但是现在发现,这本书对于Java开发,特别是性能优化有着很大的作用,如果没有去看这本书,没有理解锅Java的编译原过程和原理,这次碰到的问题就不会是两天就能解决,或者需要更长的时间,或者花了时间仍旧无法解决最后只能到处请教大神(不是说不能请教大神,只是能自己解决的问题,最好自己解决,这样才能有进步,而且大神也很忙);后续会继续努力钻研学习,多去系统的看书学习,使自己进步更快些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值