final static 常量 编译时就已经确定

本文分享了一次在修改开源包源码时因忽视staticfinal特性而失败的经历,提醒开发者在进行类似操作时需要考虑到编译时的特性及可能引发的问题。


晚上因为需求,需要更改一个开源包的源码实现一个不同的功能。正常只要修改一个常量就可以,如下:




其有很多类有引用。没注意,直接下载源码更改这个类。最后覆盖相应的class文件。最后怎么都没成功。


想起java里面一个最简单的概念,static final 在编译的时候就已经确定了,已经编译到各个引用类中了,所以,更新需要同步覆盖啊。坑爹给忘了。。。。


### 运行时常量编译时常量的区别及使用场景 运行时常量编译时常量是编程语言中两种不同类型的常量,它们在生成时间、存储位置以及使用场景上存在显著差异。以下是两者的详细对比和具体用法。 #### 1. 定义与生成时间 - **编译时常量**是指在编译阶段就已经确定常量。这类常量通常通过关键字如 `const`(C++ 中)或 `final`(Java 中)定义,并且其在程序编译时就被固定下来[^3]。 - **运行时常量**则是在程序运行过程中才确定常量。这类常量可能依赖于运行时的上下文环境,例如动态加载的数据或计算结果[^4]。 #### 2. 存储位置 - **编译时常量**直接嵌入到代码中,或者存储在静态存储区域。由于其编译时已知,因此可以直接被优化器替换为实际,从而减少运行时的内存占用[^1]。 - **运行时常量**存储在运行时数据区,例如 Java 虚拟机中的运行时常量池(Runtime Constant Pool)。运行时常量池位于方法区(Method Area),用于存储类加载时解析的符号引用和其他动态生成的常量[^4]。 #### 3. 使用场景 - **编译时常量**适用于那些在整个程序生命周期内都不会改变的。例如,数组大小、数学常数(如 π)、配置参数等。以下是一个 C++ 的例子: ```cpp const int MAX_SIZE = 100; // 编译时常量 int arr[MAX_SIZE]; // 使用编译时常量定义数组大小 ``` - **运行时常量**则适合需要在运行时动态计算或加载的。例如,从数据库读取的配置项、用户输入的参数、动态生成的标识符等。以下是一个 Java 的例子: ```java final String USER_NAME = getUserInput(); // 运行时常量由用户输入决定 System.out.println("Hello, " + USER_NAME); ``` #### 4. 性能与灵活性 - **编译时常量**由于在编译时就已确定,因此可以进行更多的优化操作,例如内联展开和常量折叠。这使得程序运行更快,但同时也意味着如果修改了某个常量,可能需要重新编译整个项目以确保一致性[^3]。 - **运行时常量**虽然无法享受编译期优化带来的性能提升,但由于其是在运行时确定的,因此具有更高的灵活性。这对于需要动态调整的行为非常有用[^4]。 ### 示例代码 以下分别展示了 C++ 和 Java 中如何定义和使用编译时常量与运行时常量: #### C++ 示例 ```cpp // 编译时常量 const int COMPILE_TIME_CONSTANT = 42; // 运行时常量 int runtimeConstant = getRuntimeValue(); ``` #### Java 示例 ```java // 编译时常量 public static final int COMPILE_TIME_CONSTANT = 42; // 运行时常量 public static final String RUNTIME_CONSTANT = calculateValueAtRuntime(); ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值