我最喜欢的 Java 面试问题,很棘手,但同时也非常有用。一些面试者也常问这个问题,为什么 String 在 Java 中是 final 的。字符串在 Java 中是不可变的,因为 String 对象缓存在 String 池中。由于缓存的字符串在多个客户之间共享,因此始终存在风险,其中一个客户的操作会影响所有其他客户。例如,如果一段代码将 String “Test” 的值更改为 “TEST”,则所有其他客户也将看到该值。由于 String 对象的缓存性能是很重要的一方面,因此通过使 String 类不可变来避免这种风险。同时,String 是 final 的,因此没有人可以通过扩展和覆盖行为来破坏 String 类的不变性、缓存、散列值的计算等。String 类不可变的另一个原因可能是由于 HashMap。由于把字符串作为 HashMap 键很受欢迎。对于键值来说,重要的是它们是不可变的,以便用它们检索存储在 HashMap 中的值对象。由于 HashMap 的工作原理是散列,因此需要具有相同的值才能正常运行。如果在插入后修改了 String 的内容,可变的 String将在插入和检索时生成两个不同的哈希码,可能会丢失 Map 中的值对象。如果你是印度板球迷,你可能能够与我的下一句话联系起来。字符串是Java的 VVS Laxman,即非常特殊的类。我还没有看到一个没有使用 String 编写的 Java 程序。这就是为什么对 String 的充分理解对于 Java 开发人员来说非常重要。String 作为数据类型,传输对象和中间人角色的重要性和流行性也使这个问题在 Java 面试中很常见。为什么 String 在 Java 中是不可变的是 Java 中最常被问到的字符串访问问题之一,它首先讨论了什么是 String,Java 中的 String 如何与 C 和 C++ 中的 String 不同,然后转向在Java中什么是不可变对象,不可变对象有什么好处,为什么要使用它们以及应该使用哪些场景。这个问题有时也会问:“为什么 String 在 Java 中是 final 的”。在类似的说明中,如果你正在准备Java 面试,我建议你看看《Java程序员面试宝典(第4版) 》,这是高级和中级Java程序员的优秀资源。它包含来自所有重要 Java 主题的问题,包括多线程,集合,GC,JVM内部以及 Spring和 Hibernate 框架等。正如我所说,这个问题可能有很多可能的答案,而 String 类的唯一设计者可以放心地回答它。我在 Joshua Bloch 的 Effective Java 书中期待一些线索,但他也没有提到它。我认为以下几点解释了为什么 String 类在 Java 中是不可变的或 final 的:1)想象字符串池没有使字符串不可变,它根本不可能,因为在字符串池的情况下,一个字符串对象/文字,例如 “Test” 已被许多参考变量引用,因此如果其中任何一个更改了值,其他参数将自动受到影响,即假设

String A="Test";
String B="Test";

现在字符串 B 调用 "Test".toUpperCase(), 将同一个对象改为“TEST”,所以 A 也是 “TEST”,这不是期望的结果。下图显示了如何在堆内存和字符串池中创建字符串。2)字符串已被广泛用作许多 Java 类的参数,例如,为了打开网络连接,你可以将主机名和端口号作为字符串传递,你可以将数据库 URL 作为字符串传递, 以打开数据库连接,你可以通过将文件名作为参数传递给 File I/O 类来打开 Java 中的任何文件。如果 String 不是不可变的,这将导致严重的安全威胁,我的意思是有人可以访问他有权授权的任何文件,然后可以故意或意外地更改文件名并获得对该文件的访问权限。由于不变性,你无需担心这种威胁。这个原因也说明了,为什么 String 在 Java 中是最终的,通过使 java.lang.String final,Java设计者确保没有人覆盖 String 类的任何行为。3)由于 String 是不可变的,它可以安全地共享许多线程,这对于多线程编程非常重要. 并且避免了 Java 中的同步问题,不变性也使得String 实例在 Java 中是线程安全的,这意味着你不需要从外部同步 String 操作。关于 String 的另一个要点是由截取字符串 SubString 引起的内存泄漏,这不是与线程相关的问题,但也是需要注意的。4)为什么 String 在 Java 中是不可变的另一个原因是允许 String 缓存其哈希码,Java 中的不可变 String 缓存其哈希码,并且不会在每次调用 String 的 hashcode 方法时重新计算,这使得它在 Java 中的 HashMap 中使用的 HashMap 键非常快。简而言之,因为 String 是不可变的,所以没有人可以在创建后更改其内容,这保证了 String 的 hashCode 在多次调用时是相同的。5)String 不可变的绝对最重要的原因是它被类加载机制使用,因此具有深刻和基本的安全考虑。如果 String 是可变的,加载“java.io.Writer” 的请求可能已被更改为加载 “mil.vogoon.DiskErasingWriter”. 安全性和字符串池是使字符串不可变的主要原因。顺便说一句,上面的理由很好回答另一个Java面试问题: “为什么String在Java中是最终的”。要想是不可变的,你必须是最终的,这样你的子类不会破坏不变性。你怎么看?

为什么 String 在 Java 中是不可变的?的更多相关文章

  1. 为什么 String 在 Java 中是不可变的(终极答案)

    为什么 String 在 Java 中是不可变的(终极答案) 我们可以从2个角度去看待这个问题: 1.为什么要设计成不可变2.如何保证不可变? 1.为什么设计不可变? 1.String对象缓存在Str ...

  2. 深入理解Java中的不可变对象

    深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象.包装器对象等,那么到底为何Java语言要这么设计,真 ...

  3. Java中的不可变类理解

    一.Java中的不可变类 不可变类(Immutable Objects):当类的实例一经创建,其内容便不可改变,即无法修改其成员变量. 可变类(Mutable Objects):类的实例创建后,可以修 ...

  4. 三、为什么String在Java中是不可更改的

    String在Java中是个不可更改的类.一个不可更改的类简单来说就是这个类的所有实例是不可以更改的.所有的实例信息在创建的时候被初始化而且信息是不可以更改的.不可更改的类有很多好处.这篇文章总结了为 ...

  5. Java中的不可变类

    概念:不可变类的意思是创建该类的实例后,该实例的属性是不可改变的.java中的8个包装类和String类都是不可变类.所以不可变类并不是指该类是被final修饰的,而是指该类的属性是被final修饰的 ...

  6. 五、String在Java中是传“引用”

    这个是Java的经典问题.许多类似的问题在stackoverflow被提问,有很多不正确或不完备的答案.如果不想太多你会认为这个问题比较简单.( The question is simple if y ...

  7. 关于java中的不可变类(转)

    如何在Java中写出Immutable的类? 要写出这样的类,需要遵循以下几个原则: 1)immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象. 2)Immuta ...

  8. java中形参的可变参数的定义(如String... args) .

    如果有下面的一个笔试题: 已知我们有如下的调用关系 logIt(”log message 1 “); logIt(”log message2”, " log message3”); logI ...

  9. String是java中的基本数据类型吗

    1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. Ja ...

随机推荐

  1. OpenStack、虚拟机以及和当前流行的k8s、Docker四者之间的关系

    一.OpenStack与虚拟机之间的关系 OpenStack使用Python语言开发,是虚拟资源管理工具,他可以协助你搜集各种资源,并加以利用以及管理,实现物理资源的高效使用和安全.虚拟化物理机这个动 ...

  2. 关于NSMutableAttributedString进行富文本 UILabel 的制作

    //1.初始化与其他无异 NSMutableAttributedString *AttributedStr2 = [[NSMutableAttributedString alloc]initWithS ...

  3. Docker仓库--registry与harbor

      搭建私有仓库的两种方式: Registry Harbor  一.registry的搭建 docker官方提供了一个搭建私有仓库的镜像registry,只需下载镜像,运行容器并暴露5000端口即可. ...

  4. 3款著名BI工具功能盘点,哪款更实用?

    随着信息技术的发展和应用, 人类进入了一个大数据时代.5G的到来也在不断影响我们的生活,很明显,5G将在世界上留下持久的印记和影响力.每秒10千兆比特的传输速度,它比4G网络的连接速度提高了100倍左 ...

  5. “四大高手”为你的 Vue 应用程序保驾护航

    全球都在处理数字化转型的问题,飞速发展的同时也为基础设施带来了一定的压力.同时许多黑客也在不断更新升级他们的攻击技术. 如果我们的应用程序有过多漏洞,被抓按住利用,就会变成大型芭比Q现场. 这也是为何 ...

  6. C#值类型回收

    函数调用在执行时,首先要在栈中为形参和局部变量分配存储空间,然后还要将实参的值复制给形参,接下来还要将函数的返回地址(该地址指明了函数执行结束后,程序应该回到哪里继续执行)放入栈中,最后才跳转到函数内 ...

  7. 【windows 操作系统】【CPU】用户模式和内核模式(用户层和内核层)

    所有的现代操作系统中,CPU是在两种不同的模式下运行的: 注意以下内容来自微软: windows用户模式和内核模式 运行 Windows 的计算机中的处理器有两个不同模式:用户模式 和内核模式 . 用 ...

  8. 广度优先搜索(BreadthFirstSearch)& 迪克斯特拉算法 (Dijkstra's algorithm)

    BFS可回答两类问题: 1.从节点A出发,有前往节点B的路径吗? 2.从节点A出发,前往节点B的哪条路径经过的节点最少? BFS中会用到"队列"的概念.队列是一种先进先出(FIFO ...

  9. JavaWeb-网络编程

    Java网络编程 推荐阅读: 计算机网络:https://www.cnblogs.com/zwtblog/tag/计算机网络/ 计算机网络基础 利用通信线路和通信设备,将地理位置不同的.功能独立的多台 ...

  10. HTTP请求过程和状态响应码

    HTTP请求过程 我们在浏览器中输入一个URL,回车之后便可以在浏览器中观察到页面内容.实际上,这个过程是浏览器向网站所在的服务器发送了一个请求,网站服务器接收到这个请求后进行处理和解析,然后返回对应 ...