Thinking in java-22 常量constant

1. 编译时常量

stackoverflow这里有相关详细Q&A.

编译时常量(compile-time constant):是在编译时能被(而且确实在)计算出来的值。
如果多次运行同一个程序,那么编译时常量在每次程序运行的时候都有相同的值。

2. 运行时常量

运行时常量(runtime constant): 是只能在程序运行时才被计算出来的值。
如果多次运行同一个程序,那么运行时常量在每次运行时可能有不同的值。

3.Demo

package fqy.iss.thinking.reuse;

import static fqy.iss.utils.Print.print;

import java.util.Random;

class Value
{
    int i; // Package access

    public Value(int i)
    {
        this.i = i;
    }
}

public class FinalData
{
    private static Random rand = new Random(10);
    private String id;

    public FinalData(String id)
    {
        this.id = id;
    }

    // Can be compile-time constants:
    private final int valueOne = 9;
    private static final int VALUE_TWO = 99;
    // Typical public constant:
    public static final int VALUE_THREE = 39;

    // Can't be compile-time constants:
    private final int i4 = rand.nextInt(20);
    static final int INT_5 = rand.nextInt(20);
    private Value v1 = new Value(11);
    private final Value v2 = new Value(22);
    private static final Value VAL_3 = new Value(33);

    // Arrays:
    private final int[] a =
    { 1, 2, 3, 4, 5, 6 };

    public String toString()
    {
        return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;
    }

    public static void main(String[] args)
    {
        FinalData fd = new FinalData("fd");
        // fd.valueOne++; //error, can't change value
        fd.v2.i++; // Object isn't constant!
        fd.v1 = new Value(9); // Ok-- not final
        for (int i = 0; i < fd.a.length; i++)
            fd.a[i]++; // Object isn't constant!
        // fd.v2 = new Value(0); //Error: Can't change reference
        // fd.VAL_3 = new Value(1);
        // fd.a = new int[3];
        print(fd);
        print("Creating new FinalData");
        FinalData fd2 = new FinalData("fd2");
        print(fd);
        print(fd2);
    }

}
//The running result:
fd: i4 = 0, INT_5 = 13
Creating new FinalData
fd: i4 = 0, INT_5 = 13
fd2: i4 = 13, INT_5 = 13

4. 常量存在意义

In the case of compile-time constant, the compiler is allowed to “fold” the constant value into any calculations in which it’s used; that is, the calculation can be performed at compile time, eliminating some run-time overhead. In Java, these sorts of constants must be primitives and are expressed with the final keyword. A value must be given at the time of definition of such a constant.
A field that is both static and final has only one piece of storage that cannot be changed.
When final is used with objects references rather than primitives, the meaning can be confusing. With a primitive, final makes the value a constant, but with an object reference final makes the reference a constant. Once the reference is initialized to an object, it can never be changed to point to another object. However, the object itself can be modified; Java doesn’t provide a way to make any arbitrary object a constant.
对于编译时常量而言,编译器可以将常量值在编译时计算出来,这就减少了运行时的开销;Java中这些值必须是基本数据类型,且要被final修饰。这些值必须在定义时被赋值。
特别的,如果一个类成员被声明为static final的,那么该成员在内存中只存储一份,且不能被改变。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值