为什么这里要使用final关键字?

3

我从书籍《Java编程思想》中学习Java技术。在第216页有一个例子,其中使用了final关键字来修饰其中的一个变量。

private static final Random randomNumbers = new Random();

据我所理解,变量中的final声明意味着该变量是一种常量,这意味着当它被初始化后,你就无法再更改它了。 但是上述对象(变量)在程序中被用于两次以返回随机数。
int die1 = 1 + randomNumbers.nextInt( 6 );
int die2 = 1 + randomNumbers.nextInt( 6 );

它返回2个不同(随机)的值。我认为我在这里失去了一些东西。程序运行良好,但我不明白在对象声明中使用final的目的是什么?

7个回答

12
final 意味着这里的 变量 不能改变其值 - 实际上它确实不能也不会改变。
在这里,randomNumbers 变量的值是指向 Random 实例的 引用。即使该实例每次调用 nextInt 时产生(可能)不同的数字,它仍然指向相同的实例。
需要区分变量不改变值和它所引用对象的内部状态不改变的情况。例如,你可以有这样一个例子:
public class Person {
    private final List<Person> friends = new ArrayList<Person>();

    public void addFriend(Person friend) {
        friends.add(friend);
    }

    ...
}

这里我们只有一个列表 - 你永远不能改变friends指向不同的对象 - 但是我们仍然可以改变变量所指向的列表。


那么这是否意味着,如果在程序后面我试图更改 randomNumbers,例如 randomNumbers = Random(123456),它会在编译时显示错误? - blekione

2

Final意味着一旦初始化,就不能更改引用变量。

For example

final Object obj = new Object();  //initialized 

now that doesnot mean that u cant call methods on obj

obj.someOperation1() //allowed
obj.someOperation2() //allowed
obj.anyOperationAnyTime() //allowed


But u cant assign new object to referance obj
final Object obj = new Object();  //initialized 
obj =  new Object() //now allowed , you cant make obj to point to new referance

2
除了Jon所说的,final的目的是避免在应用程序生命周期的不同阶段引用两个Random类实例。最明显的目的是避免不必要的对象创建。然而,使其final的最重要(也是最合乎逻辑的)原因是保持randomNumbers的公平性。我的意思是,当您连续调用randomNumbers上的nextInt时,返回的结果必须是唯一的、随机的,并且与以前的结果有很高的概率不同。假设您不将其设置为final,则稍后的另一个Random实例可能会开始给出与之前Random实例的结果相比重复的值。为了避免这种情况,必须将randomNumbers设置为final。

如果我可以接受两个答案作为我的问题的答案,我也会接受你的。谢谢。 - blekione

2

一个词,当你使引用类型或基本类型为final时,它是不可变的。也就是说,您不能再更改其值。

据我所知,在变量中声明final意味着该变量是一种常量,

这只是半对的,如果您将变量标记为final,则不一定意味着它是常量。使用static final将变量设置为常量。


2

- 将变量声明为final将表明该变量的值不可更改。

private static final Random randomNumbers = new Random();

- 在上述代码行中,randomNumbersRandom 类型的对象引用变量,因为它被标记为final,所以它将始终与那个特定的 Random 对象关联在一起。

- 非常重要的一点是,Random 对象没有锁定,但 对象引用变量 randomNumbers 与那个特定的 Random 对象锁定在一起

注意:

final 变量 :其值不可更改

final 方法 :无法被覆盖

final 类 :无法被扩展

final 参数 :其值不可更改,接收自调用方的参数

final 对象引用变量 :不能引用除当前所引用的对象之外的任何其他对象


那么在我的情况下,这是“最终的对象引用变量”,对吗? - blekione

0

将随机引用(randomNumbers)设置为final意味着您无法为此特定引用分配另一个值。

也就是说,以下两个语句都将在编译时进行检查/报告。

a. randomNumbers = new Random(); 

b. Random someOtherRandomNumbers = new Random(); 
   randomNumbers = someOtherRandomNumbers; 

0

randomNumbers的类型是Random。也就是说,randomNumbers是一个final对象。不能将任何其他Random对象分配给它。而你只是调用了该randomNumbers对象的方法两次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接