a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 124|回复: 1

[基础知识] JAVA基础:解决JAVA修改类文件编译不生效的方法

[复制链接]
发表于 2012-8-4 12:37:27 | 显示全部楼层 |阅读模式
首要针对的是措置全局性常量的情形   public class AppConst {9 B# t% c5 {6 x7 f+ E. g  f
  public static final String STR_CONST_1 = "String1";
# M' w3 b" ]- m* d  public static final String STR_CONST_2 = "String2";) C. }' z) ]  ]' I
  ......
$ D) ?; e! J: ~$ ?5 X  }
0 r9 s% T5 ?! Z1 f0 e3 W  界说了一个常量类琅缦沔界说了我们需要用到的常量值!
' u) w$ l9 B9 w8 y6 j. a  然后在某些逻辑代码段里使用了这些常量。这样做可以便于打点常量,避免了年夜量的magic number/text,在改削常量内容时只需改章矣闽类就行了,但有时辰会奇异地发现,年夜头编译打包的轨范依旧我行我素,并没有即时纺暌钩我们对常量的改削,这是何解呢?0 I. Q( s8 N) r' d
  在之前的《JVM进修标识表记标帜三--类的初始化》中我曾提到,静态常量(寄暌姑 static final 润色的变量)是编译时常量,当一个class文件编译完毕,它内部使用到的所有常量的具膛鲎磐已经确定了,不能想当然地觉得它在运行时并毗连常量打倒謇霎后才会以引用体例使用常量。好比下面这段代码:
; P7 ~* v2 F+ ~3 ?( ^; F% f/ {/ e  import AppConst;2 ^* l3 i% A1 m: A0 I
  public class SomeService {% l, N3 W! ~- K$ E7 O
  public void serviceJob1() {
7 }' F  b1 I6 b8 K! ~4 d  System.out.println(AppConst.STR_CONST_1);
* c& `; R9 e: ?; u. @, c  }
$ |& E! {1 o5 ?0 L7 B5 M5 W  }
3 J! u1 B- @. e  K& h  类SomeService使用了STR_CONST_1这个常量,概况上是经由过程AppConst类取得的这个值,现实上在SomeService被编译后,其代码其实酿成了  s6 P$ ^0 a- g: j( Q1 F7 f
  public class SomeService {
3 W* |9 F: R+ F$ q) ^: a  public void serviceJob1() {
9 a8 l4 M6 v* E& k* K  System.out.println("String1");
, k: Z3 A0 z( }+ ^  }, R% t! g* @: Z# U* ?
5 R- W. K8 k2 M
  }
回复

使用道具 举报

 楼主| 发表于 2012-8-4 12:37:28 | 显示全部楼层

JAVA基础:解决JAVA修改类文件编译不生效的方法

</p>  这琅缦沔到净有AppConst什么事,所以你即使改削了AppConst的相关常量,令STR_CONST_1 = "NotString1",SomeService可能依然会打印"String1",因为SomeService的代码没有任何改削,在增量编译的情形下,它的class文件不会被年夜头编译。
, ]& r3 w# f# e1 w  年夜白了膳缦沔这些,年夜致就知道怎么办了,我的体例有两个:6 K7 k& z' j$ V2 R- R4 o4 t
  1. 原始前提下,删除class文件后手动重编译。
6 a* \' B1 |7 M8 ^! q5 T  2. 使用IDE的时辰, 先对SomeService做一个细微改削并保留(会自动编译),然后再改削回来并保留(再次自动编译)。如斯class文件就会被更新了。! U" z+ ?, W/ ], w  u
  声名:这就是为什么要把全数的.class文件删除失踪了。2 R9 U- u* t& h7 J. {
  填补:5 {( q0 h% }9 @" G9 ?% }7 y
  改成
. W1 m2 G+ B* z; h  1. public class AppConst {6 f7 ~0 @- B. P2 O; ~0 D
  2.9 \5 f+ D4 ]) ~+ a1 H: j' p
  3.: V& t5 Z$ q3 {' r: y% x
  public static getString2(){
! [# ~) ?, ?$ I6 d' w. H* i8 m  return "String2";
' [/ y% `5 i: k( F) g  }
# h3 ?7 j7 o6 ~  4.     ......
$ u& h* H$ T! t, |% _- A( V  5. }
( v3 _* Z* m1 A$ f! k* {5 u( Y  就可以仅仅改削并编译一个类就行了  h6 [# R- `8 L! L. R" `$ |6 v
  年夜根柢上来解决此问题得这么做,最简单。
7 D! M6 M7 \1 \0 F# m# g  public class AppConst {
3 i; h; M  q, O( B. b  public static final String STR_CONST_1 = new String("String1");. i9 U7 n' C) C3 L4 T
  public static final String STR_CONST_2 = new String("String2");/ Z6 ]9 ~5 U4 _; R: b
  public static final int number1=new Integer(123);$ Z2 _: {0 K5 q8 e" t. r
  ......# D6 g/ r+ ^& N+ Z0 M3 w
  }  K( Q( J  D  v/ G$ F- {
  反编译,你会发此刻引用此静态类属性的时辰,引用代码不是直接器具体值替代,而仍是源代码里的引用。
0 B! n# ?( }- f2 u' M# J  一句话总结,在静态类里界说的静态属性,果断不用引用类型,而需要用对象类型。2 ~- \2 ?2 b* q8 {" Q4 i% ?
  结论:
5 z- K5 d4 K( U8 c3 [" c6 e  解决这种问题总共有三种体例:
; G5 z! G4 i) _6 z/ O* `7 Y  1、将全数的CLASS文件删除失踪再编译* [, h% H  G% f& U$ E. v
  2、将其酿成GET、SET体例
: T5 H# L( e( T/ m& z9 A8 I  3、设置核对象引用的体例措置!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-16 08:28 , Processed in 0.293493 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表