`
jeff312
  • 浏览: 76196 次
  • 性别: Icon_minigender_1
  • 来自: 新加坡
社区版块
存档分类
最新评论

更新常量后,请重新编译你的class

    博客分类:
  • J2EE
阅读更多
    一些朋友可能喜欢这样做,程序中使用的各种常量用一个类来统一管理,类似:
public class AppConst {
    public static final String STR_CONST_1 = "String1";
    public static final String STR_CONST_2 = "String2";
    ......
}


    然后在某些逻辑代码段里使用了这些常量。这样做可以便于管理常量,避免了大量的magic number/text,在修改常量内容时只需改这一个类就行了,但有时候会奇怪地发现,重新编译打包的程序依旧我行我素,并没有即时反应我们对常量的修改,这是何解呢?

    在之前的《JVM学习笔记三--类的初始化》中我曾提到,静态常量(即用 static final 修饰的变量)是编译时常量,当一个class文件编译完毕,它内部使用到的所有常量的具体值就已经确定了,不能想当然地以为它在运行时并连接常量管理类之后才会以引用方式使用常量。比如下面这段代码:
import AppConst;
public class SomeService {
    public void serviceJob1() {
        System.out.println(AppConst.STR_CONST_1);
    }
}

类SomeService使用了STR_CONST_1这个常量,表面上是通过AppConst类取得的这个值,实际上在SomeService被编译后,其代码其实变成了
public class SomeService {
    public void serviceJob1() {
        System.out.println("String1");
    }
}

这里面根本没有AppConst什么事,所以你即使修改了AppConst的相关常量,令STR_CONST_1 = "NotString1",SomeService可能依然会打印"String1",因为SomeService的代码没有任何修改,在增量编译的情况下,它的class文件不会被重新编译。

明白了上面这些,大致就知道怎么办了,我的方法有两个:
1. 原始条件下,删除class文件后手动重编译。
2. 使用IDE的时候, 先对SomeService做一个细微修改并保存(会自动编译),然后再修改回来并保存(再次自动编译)。如此class文件就会被更新了。
分享到:
评论
7 楼 sjavaboy 2010-10-26  
eclipse 不是自动编译的啊。
6 楼 zhangyou1010 2010-01-27  
zpchen 写道
从根本上来解决此问题得这么做,最简单。
public class AppConst {  
    public static final String STR_CONST_1 = new String("String1");  
    public static final String STR_CONST_2 = new String("String2");  
    public static final int number1=new Integer(123);
    ......  
}
反编译,你会发现在引用此静态类属性的时候,引用代码不是直接用具体值替代,而还是源代码里的引用。

一句话总结,在静态类里定义的静态属性,坚决不用引用类型,而需要用对象类型。

不太明白楼上的 "一句话总结,在静态类里定义的静态属性,坚决不用引用类型,而需要用对象类型。" ?
5 楼 zpchen 2010-01-26  
从根本上来解决此问题得这么做,最简单。
public class AppConst {  
    public static final String STR_CONST_1 = new String("String1");  
    public static final String STR_CONST_2 = new String("String2");  
    public static final int number1=new Integer(123);
    ......  
}
反编译,你会发现在引用此静态类属性的时候,引用代码不是直接用具体值替代,而还是源代码里的引用。

一句话总结,在静态类里定义的静态属性,坚决不用引用类型,而需要用对象类型。
4 楼 njyu 2010-01-06  
学习 学习  学习
3 楼 windmerlin 2010-01-03  
<p>这个问题已经很早了!楼上的说的方法不错,直接写出 get 和 set 方法 。调用方法的话只需要重新编译 设置静态常量的那个类就可以了</p>
2 楼 NanguoCoffee 2010-01-02  
改成
   1. public class AppConst { 
   2.   
   3.    
          public static getString2(){
              return "String2"; 
          }
   4.     ...... 
   5. } 

就可以仅仅修改并编译一个类就行了
1 楼 yanwt 2010-01-01  
是这样的,单纯的修改静态变量是没用的,还要重新编辑所有引用静态变量的类,不然不会生效的。

相关推荐

    反编译工具,能将.class反编译成.java,但是和源码有些不一样,因为它会有些常量优化和其他的东西。

    反编译工具,能将.class反编译成.java,但是和源码有些不一样,因为它会有些常量优化和其他的东西。

    JVM常量池教程吐血整理干货.md

    当Java源文件被编译后,就会生成Class字节码文件。 Class常量池就存在于Class文件中(Class文件的Constant Pool中)。 Class文件常量池主要存放两大常量:字面量和符号引用。 字面量: 字面量分为文本字符串(如: "abc...

    C++编译期间类中的常量

    问题:在类中建立一个int类型的数组  方法一:(错误)  class Test  {  const int size = 100;  int array[size];  //……  };

    JD-GUI,JDGUI,java反编译工具

    java反编译工具: JD-GUI JD-GUI 是一个用 C++ 开发的 Java 反编译工具... (它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。)

    java反编译class源码-cardboard:CardboardVR工具包库(反编译源)

    java反编译class源码#Google Cardboard VR 工具包库项目 注意:这是使用 JD-GUI 从 JAR 反编译的。 没有保证。 目前 cardboard.jar 与寻宝纸板样本一起以二进制形式提供 谷歌(+Christian Plagemann)在谷歌+ ...

    delphi编译错误.txt

    Class or object types only allowed in type section 在类型区段只允许有类或对象类型 Class type required 需要类类型 Close error on &lt;Filename&gt; 文件关闭错误 Compile terminated by user 用户中止编译 Constant...

    解析C#中的常量及如何在C#编程中定义常量

    常量是在编译时已知并在程序的生存期内不发生更改的不可变值。常量使用 const 修饰符进行声明。只有 C# 内置类型(System.Object 除外)可以声明为 const。 用户定义的类型(包括类、结构和数组)不能为 const。请...

    Java常量的定义

     由于java interface中声明的字段在编译时会自动加上static final的修饰符,即声明为常量。  public interface Constants{  String name = 111;  }  public class read{  public static void main...

    matlab语言dll反编译成源码-2019-:2019-

    matlab语言dll反编译成源码 :bookmark_tabs: 目录 :plus: C/C++ const 作用 修饰变量,说明该变量不可以被改变; 修饰指针,分为指向常量的指针和指针常量; 常量引用,经常用于形参类型,即避免了拷贝,又避免了...

    Ming:Class文件解析器

    MingClass文件解析器关于对Java编译后的Class文件进行解析版本(更新说明)0.1.0修复读取Double和Long类型时出现找不到指定类型的错误移除jdk9的方法InputStream#readAllBytes(),替换为Files#readAllBytes(),以支持...

    LuaBind 源码 (Lua增强库)

    这意味着,你不需要额外的预处理过程去编译你的工程(编译器 会替你完成全部的工作).这还意味着,你也不需要(通常)知道你注册的每一个函数的精确的签名. 因为,LuaBind库会在编译时生成所需的代码.这样做的不利点是,编译...

    java接口方法概述集合详解.docx

    1、接口是Java语言中的一种引用类型,是方法的"集合",...它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。 public class 类名.java–&gt;.class public interface 接口名.java–&gt;.class

    编译原理实验报告--词法分析器

    public class AnalyseWords { private List&lt;String&gt; temp = new ArrayList(); public List&lt;String&gt; getTemp() { return temp; } /* 关键字或者标识符的长度。 */ private static final int LENGTHOFKEYWORDS...

    大白话带你认识JVM.pdf

    方法区 是用于存放类似于元数据信息方面的数据的,比如类信息,常量,静态变量,编译后代码···等 类加载器将 .class 文件搬过来就是先丢到这一块上 #③ 堆 堆 主要放了一些存储的数据,比如对象实例,数组··...

    Java7虚拟机规范(高清带目录)

    《Java虚拟机规范(Java SE 7版)》是Java领域最重要和最...第4章深入分析了用来表示编译后的类和接口的class文件格式,主要包括ClassFile结构、描述符与签名、常量池、字段、方法、属性、代码约束与class文件校验等。

    C#基础:基于const与readonly的深入研究

    而readonly常量却有一点不同,那就是其值可以在运行时编译,当然,它也必须遵守作为常量的约束,那就是值必须恒定不变。•const常量必须在声明的同时对其进行赋值,并且确保该值在编译时可确定并恒定;而readonly...

    java虚拟机规范 jdk8.

     深入分析用来表示编译后的类和接口的class文件格式,主要包括ClassFile文件结构、描述符、常量池、字段、方法、属性、格式检查、代码约束与class文件校验等。  定义Java虚拟机启动以及类和接口的加载、链接和初始...

    Flash 反编译工具(JPEXS Free Flash Decompiler) v3.0 中文版.zip

    - 常量池会自动更新 AS3 :添加新特性 - 添加新的方法或者插槽/常量到现有的类 工具 内置代理 搜索ActionScript源(文本或正则表达式) 转至文档类( AS3 ) 代理 - 配置您的浏览器使用我们的代理 - 代理...

    【带书签】Java虚拟机规范(Java SE 7).pdf

    第4章深入分析了用来表示编译后的类和接口的class文件格式,主要包括ClassFile结构、描述符与签名、常量池、字段、方法、属性、代码约束与class文件校验等。第5章定义了Java虚拟机启动以及类和接口的加载、链接和...

    Java虚拟机规范(Java SE 7)中文版

    第4章深入分析了用来表示编译后的类和接口的class文件格式,主要包括ClassFile结构、描述符与签名、常量池、字段、方法、属性、代码约束与class文件校验等。第5章定义了Java虚拟机启动以及类和接口的加载、链接和...

Global site tag (gtag.js) - Google Analytics