Ale*_*lex 134 java string final
从我得知该类java.lang.String在Java中被宣布为final时,我想知道为什么会这样?当时我没有找到任何答案,但这篇文章:如何在Java中创建String类的副本?让我想起了我的疑问.
当然,String提供了我所需要的所有功能,并且从未想过任何需要扩展String类的操作,但你仍然永远不会知道某人可能需要什么!
那么,有没有人知道设计师在决定最终时的意图是什么?
Bru*_*eis 86
将字符串实现为不可变对象非常有用.您应该阅读有关不可变性的内容,以便更多地了解它.
不可变对象的一个优点是
您可以通过将重复项指向单个实例来共享重复项.
(从这里).
如果String不是最终的,你可以创建一个子类,并且当"被视为字符串"时有两个看起来很相似的字符串,但这实际上是不同的.
Anu*_*rag 59
这是一篇很好的文章,概述了上述答案中已经提到的两个原因:
这可能是该文章中最详细的评论.它与Java中的字符串池和安全问题有关.它关于如何决定进入字符串池的内容.假设两个字符串相等,如果它们的字符序列相同,那么我们就有一个竞争条件,即谁先到达那里以及它的安全问题.如果没有,那么字符串池将包含冗余字符串,从而失去了首先使用它的优势.只是为自己读一读,是吗?
扩展字符串会对平等和实习造成严重破坏.JavaDoc说等于:
将此字符串与指定的对象进行比较.当且仅当参数不为null并且是表示与此对象相同的字符序列的String对象时,结果才为真.
假设java.lang.String不是最终的,a SafeString可以等于a String,反之亦然; 因为它们代表相同的字符序列.
如果您申请intern了SafeString- 会SafeString进入JVM的字符串池会发生什么?然后ClassLoader,SafeString保持引用的所有对象将在JVM的生命周期内锁定到位.你会得到一个关于谁可能是第一个实习一系列角色的竞争条件 - 也许你SafeString会赢,也许是一个String,或者可能是SafeString由不同的类加载器(因此是不同的类)加载.
如果你赢得了比赛,这将是一个真正的单身人士,人们可以通过反射和访问你的整个环境(沙箱)secretKey.intern().getClass().getClassLoader().
或者JVM可以通过确保只向池中添加具体的String对象(并且没有子类)来阻止此漏洞.
如果实现了equals,那么SafeString!= Stringthen SafeString.intern!= String.intern,并且SafeString必须添加到池中.然后池将成为一个池<Class, String>而不是<String>你需要进入池中的所有池将是一个新的类加载器.
小智 25
String是不可变的或最终的绝对最重要的原因是它被类加载机制使用,因此具有深刻和基本的安全方面.
如果String是可变的或不是最终的,加载"java.io.Writer"的请求可能已被更改为加载"mil.vogoon.DiskErasingWriter"
reference:为什么String在Java中是不可变的
Thi*_*ilo 15
String 在Java中是一个非常核心的类,许多东西依赖于它以某种方式工作,例如是不可变的.
使类final可以防止可能破坏这些假设的子类.
请注意,即使是现在,如果使用反射,也可以破坏字符串(更改其值或哈希码).可以使用安全管理器停止反射.如果String不是final,每个人都可以做到.
其他未声明的类final允许您定义有些破坏的子类(例如,您可能List会将其添加到错误的位置),但至少JVM不依赖于其核心操作.
正如布鲁诺所说,这是关于不变性的.这不仅仅是关于字符串,还有关于任何包装器,例如Double,Integer,Character等.这有很多原因:
基本上它是这样的,作为程序员,您可以确保您的字符串永远不会被更改.它也是,如果你知道它是如何工作的,可以改善内存管理.尝试一个接一个地创建两个相同的字符串,例如"hello".如果您调试,您会注意到它们具有相同的ID,这意味着它们完全是同一个对象.这是因为Java允许你这样做.如果字符串是可变的,这将是不可能的.他们可以拥有相同的等等,因为它们永远不会改变.因此,如果您决定创建1,000,000字符串"hello",那么您真正要做的就是创建1,000,000个指向"hello"的指针.同样地将字符串或任何包装器上的任何函数联合起来将导致创建另一个对象(再次查看对象ID - 它将改变).
Java中的最终版本并不一定意味着对象不能改变(例如C++不同).这意味着它指向的地址不能更改,但您仍然可以更改其属性和/或属性.因此,在某些情况下理解不变性和最终性之间的差异可能非常重要.
HTH
参考文献: