gpt4 book ai didi

java - 为什么 String 类是不可变的,即使它有一个名为 "hash"的非最终字段

转载 作者:IT老高 更新时间:2023-10-28 20:45:41 24 4
gpt4 key购买 nike

我正在阅读 Effective Java 的第 15 项约书亚布洛赫。在谈到“最小化可变性”的第 15 条中,他提到了使对象不可变的五个规则。其中之一是使所有字段最终。这是规则:

Make all fields final : This clearly expresses your intent in a manner that is enforced by the system. Also, it is necessary to ensure correct behavior if a reference to a newly created instance is passed from one thread to another without synchronization, as spelled out in the memory model [JLS, 17.5; Goetz06 16].

我知道 String 类是不可变类的一个例子。通过source code我看到它实际上有一个不是最终的哈希实例。

//Cache the hash code for the string
private int hash; // Default to 0

String 是如何变成不可变的呢?

最佳答案

这句话解释了为什么这不是最终的:

//Cache the hash code for the string

这是一个缓存。如果您不调用 hashCode,则不会设置它的值。它可以在创建字符串期间设置,但这意味着更长的创建时间,对于您可能不需要的功能(哈希码)。另一方面,每次询问时都计算哈希值会很浪费,因为字符串是不可变的,并且哈希码永远不会改变。

存在非最终字段的事实确实与您引用的定义有些矛盾,但在这里它不是对象接口(interface)的一部分。它只是一个内部实现细节,对字符串的可变性(作为字符容器)没有影响。

编辑 - 由于大众需求,完成我的回答:虽然 hash 不是公共(public)接口(interface)的直接部分,但它可能会影响该接口(interface)的行为,如 hashCode 返回它的值。现在,由于 hashCode 不同步,如果多个线程同时使用该方法,则可能会多次设置 hash。但是,设置为 hash 的值始终是稳定计算的结果,它仅依赖于最终字段(valueoffset计数)。因此,哈希的每次计算都会产生完全相同的结果。对于外部用户,这就像 hash 被计算一次一样 - 就像它每次都被计算一样,因为 hashCode 的合约要求它始终如一对于给定值返回相同的结果。最重要的是,即使 hash 不是最终的,它的可变性对外部查看者永远是不可见的,因此可以认为该类是不可变的。

关于java - 为什么 String 类是不可变的,即使它有一个名为 "hash"的非最终字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11282219/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com