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

Java不可变类?

淳于升
2023-03-14
问题内容

我找到了一篇有趣的代码文章:

public class Employee {

    private String firstName;
    private String lastName;

    //private default constructor
    private Employee(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public static Employee valueOf (String firstName, String lastName) {
        return new Employee(firstName, lastName);
    }
}

我真的很好奇了解创建此类的优势。我知道这里的此类对象是不可变的,因为一旦初始化就无法更改其变量值。我以前从未做过这样的事情,而且我真的不了解它的优势。

  • 为什么是个好习惯?
  • 您能说出可以使用这种方法的情况吗?
  • 常量或只读变量呢?那不是很相似吗?
  • 在文章中说,这不利于应用程序的性能。 但是为什么 呢?

问题答案:

您提到的示例是不可变对象。它在编程语言中被广泛使用的概念。

从上面的链接报价。优点是

  • 易于构建,测试和使用
  • 自动是线程安全的,没有同步问题
  • 不需要复制构造函数
  • 不需要克隆的实现
  • 允许hashCode使用延迟初始化,并缓存其返回值
  • 用作字段时不需要防御性地复制
  • 制作好Map键和Set元素(这些对象在集合中时不得更改状态)
  • 在构造时就建立了其类不变式,因此不再需要检查
  • 总是具有“失败原子性”(约书亚·布洛赫(Joshua Bloch)使用的术语):如果一个不可变的对象-引发异常,则它永远不会处于不希望的状态或不确定的状态


 类似资料:
  • 问题内容: 通过遵循所有Java标准,我的班级变得一成不变 这些是我在定义不可变类时所做的主要检查点。 但是还有一个问题,我的对象仍然可以通过java反射进行修改,对吗?还是我在课堂上错过了任何一点? 提前致谢。 问题答案: 没有什么可以躲藏的-即使是不可变的类也不能幸免。但是,您对此无能为力,因此“无法通过反射进行修改”不是不变性的标准之一。

  • 问题内容: 从Java 1.6 Collection Framework文档中 : 不支持任何修改操作(如类别,和)被称为 不可修改的 。[…]额外保证Collection对象中的任何更改都将不可见的Collection被称为 不可变的 。 第二个标准使我有些困惑。鉴于第一个集合是不可修改的,并且假定原始集合引用已被删除,那么第二行中提到的更改是什么?它是指集合中包含的元素的变化,即元素的状态吗?

  • 问题内容: 在有效Java中,Bloch建议使所有字段最终成为使对象不变的对象。 是否有必要这样做?不只是不提供访问器方法就使其不可变。 例如 上述类是不可变的,即使我不申报的吗?我想念什么吗? 问题答案: 除了@Bozho的要点之外,将字段声明为意味着可以安全地访问它而无需任何同步。 相反,如果该字段不是,则存在另一个风险,即如果另一个线程在没有适当同步的情况下访问该字段,则另一个线程将看到该字

  • 问题内容: 为了使一类不变,我可以做的是: 1)将类设为final 2)不提供设置器 3)将所有变量标记为final 但是,如果我的班级有另一个班级的另一个对象,那么somone可以更改该对象的值 问题答案: A)也使不可变 要么 B)不允许直接访问对象,而是仅提供获取器以充当代理。 编辑添加: 您 可以 制作一个深层副本并返回一个副本,而不是原始副本,但这通常不是您在Java中期望的行为类型。

  • 所以我创建了速度可变与不变的简单测试: 如果测试运行得太慢/太快,您可以调整数组得大小. 我使用:-server-xms256m-xx:+actursiveopts运行,得到:

  • 本文向大家介绍JAVA不可变类(immutable)机制与String的不可变性(推荐),包括了JAVA不可变类(immutable)机制与String的不可变性(推荐)的使用技巧和注意事项,需要的朋友参考一下 一、不可变类简介 不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值。如JDK内部自带的很多不可变类:Interger、Long和String等。 可变类:相对