关于Java常量的困惑

时间:2014-11-11 10:41:49

标签: java constants

我正在研究java编程,我对常量有点困惑。从我到目前为止所读到的常量是最终的,不能像变量一样重新分配新的值。但是,当我使用Calender类时,set方法似乎改变了一个常量字段。例如:

Calendar cal = Calendar.getInstance();
System.out.println("The year is " + cal.get(Calendar.YEAR));
cal.set(Calendar.YEAR, 2001);
System.out.println("The year is " + cal.get(Calendar.YEAR));

如果Calendar.YEAR类中的final字段已声明为Calendar,那么为什么我可以使用set方法将其更改为其他值?

4 个答案:

答案 0 :(得分:5)

Calendar.YEAR只是在日历中设置 逻辑字段的常量。

目的是避免使用带

的API
setYear
setDay
setMonth
...

回想起来,我认为这是一个非常糟糕的主意 - 以及java.util.Calendarjava.util.Date的其余大部分设计。

所以这个电话:

cal.set(Calendar.YEAR, 2001)

不会更改Calendar.YEAR的值...它会更改Calendar对象中的其他(私有)字段。

答案 1 :(得分:3)

Calendar.set(Calendar.YEAR, xx)更改年份的值(对于日历实例),而不是Calendar.YEARwhich is 1)的值,请参阅javadoc

注意:很容易让short program来验证。

答案 2 :(得分:3)

实际上calendar.set(blah, blahVal)没有更新第一个参数(Calendar.YEAR),它会更新日历内部维护的值, 例如,如果您提供cal.set(Calendar.YEAR, 2001) Calendar.YEAR是一个常量,它是数组的索引。该数组包含指定的值。这个价值会急剧更新。

答案 3 :(得分:1)

Calendar.YEAR只是一个int,在Constant Field Values中定义,请参阅docs

public static final int YEAR

它不会更改常量字段,此int定义应更改的字段,请参阅source code

1196    public void set(int field, int value)
1197    {
1198        if (isLenient() && areFieldsSet && !areAllFieldsSet) {
1199            computeFields();
1200        }
1201        internalSet(field, value);
1202        isTimeSet = false;
1203        areFieldsSet = false;
1204        isSet[field] = true;
1205        stamp[field] = nextStamp++;
1206        if (nextStamp == Integer.MAX_VALUE) {
1207            adjustStamp();
1208        }
1209    }

查看docs Calendar#set以更好地了解它的作用。