当前位置: 首页 > 面试题库 >

Java 什么是不变的?

谢涵煦
2023-03-14
问题内容

这可能是有史以来最愚蠢的问题,但我认为对于Java新手来说,这非常令人困惑。

  1. 有人可以澄清什么是不变的吗?
  2. 为什么是String一成不变的?
  3. 不可变对象的优点/缺点是什么?
  4. 为什么诸如StringBuilderString之类的可变对象优先于String,反之亦然?

一个很好的例子(在Java中)将不胜感激。


问题答案:

不可变是指一旦对象的构造函数完成执行,该实例将无法更改。

这很有用,因为它意味着你可以传递对对象的引用,而不必担心别人会更改其内容。尤其是在处理并发时,永远不变的对象没有锁定问题

例如

class Foo
{
     private final String myvar;

     public Foo(final String initialValue)
     {
         this.myvar = initialValue;
     }

     public String getValue()
     {
         return this.myvar;
     }
}

Foo不必担心调用方getValue()可能会更改字符串中的文本。

如果你想象与相似的类Foo,但是成员带有StringBuilder而不是String,则可以看到的调用者getValue()将能够更改实例的StringBuilder属性Foo。

还要注意你可能会发现的各种不变性:埃里克·利珀特(Eric Lippert)撰写了一篇有关此的博客文章。基本上,你可以拥有其接口是不可变的对象,但是在幕后是实际的可变私有状态(因此不能在线程之间安全地共享)。



 类似资料:
  • 问题内容: 我搜索了该主题,但是除了Wikipedia之外,我没有找到任何其他有用的文档或文章。 有人可以用简单的词向我解释这意味着什么,还是可以使我参考一些易于理解的好文档? 问题答案: 对于Java而言,这并不意味着什么。 类不变式只是一个属性,它始终为一个类的所有实例保存,无论其他代码做什么。 例如, X具有不变的类,即存在一个属性,并且永远不存在,并且它具有type值。 无法保持两个重要的

  • 问题内容: 我知道整数在Java中是不可变的。但是为什么要这样设计呢? 我找不到强制Integer不可变的用例。是否有类似String的技术原因? 字符串在网络连接,数据库URL等中用作参数。如果它是可变的,则很容易遭到破坏。 支持StringPool功能。 支持使用字符串作为参数的类加载机制。字符串可变会导致加载错误的类。 我知道有些包装很易变。 更新: 从对话中,并没有普遍的理由要求整数是不可

  • 问题内容: 有人问我为什么String是不可变的 我这样回答: 当我们在Java中像这样创建一个字符串时,;将在字符串pool(hello)中创建一个对象,并且s1将指向hello。现在再次执行该操作;将不会创建另一个对象,但是s2将指向该对象,hello 因为JVM将首先检查如果在字符串池中是否存在相同的对象, 如果不存在则仅创建一个新对象。 现在,如果假设Java允许串可变那么如果我们改变S1

  • 问题内容: 摘自Joshua Bloch的Effective Java, 数组在两个重要方面不同于通用类型。第一数组是协变的。泛型是不变的。 协变量仅表示如果X是Y的子类型,则X []也将是Y []的子类型。数组是协变的,因为字符串是Object的子类型,所以 不变式仅表示X是否为Y的子类型, 问题答案: Java和C#的早期版本不包含泛型(又称参数多态性)。 在这种情况下,使数组不变会排除有用的

  • 问题内容: 我知道适用于一般不可变类的常见原因,即 不能改变为副作用 容易推断他们的状态 本质上是线程安全的 无需提供克隆/复制构造函数/工厂复制方法 实例缓存 无需防御副本。 但是,包装器类表示原始类型,并且原始类型是可变的。那么为什么包装器类不可变? 问题答案: 但是,包装器类表示原始类型,并且原始类型(String除外)是可变的。 首先,String不是原始类型。 其次,谈论原始类型是可变的

  • 本文向大家介绍String 为什 么是不可变的?相关面试题,主要包含被问及String 为什 么是不可变的?时的应答技巧和注意事项,需要的朋友参考一下 简单的来说:String 类中使用 final 关键字修饰字符数组来保存字符串,`private final char value[]`,所以 String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 Ab