当前位置: 首页 > 知识库问答 >
问题:

如何在java中使对象不可变

商茂勋
2023-03-14

由于这是一个热门的话题,这些天,我无法理解某些概念。请原谅,如果我听起来很愚蠢,但当我试图创建不可变对象时,我发现大多数帖子如下

    null
    null
    public final class ImmutableUser {
    private final UUID id;
    private final String firstName;
    private final String lastName;

    public ImmutableUser(UUID id, String firstName, String lastName) {
        super();
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    /**
     * @return the id
     */
    public UUID getId() {
        return id;
    }
    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }
    /**
     * @return the lastName
     */
    public String getLastName() {
        return lastName;
    }
}
public class ImmutableUserTest {

        @Test(expected = IllegalAccessException.class)
        public void reflectionFailure() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
            ImmutableUser user = new ImmutableUser(UUID.randomUUID(), "john", "liu");
            Field i =user.getClass().getDeclaredField("firstName");
            i.setAccessible(true);
            i.set(user, "cassandra");
            System.out.println("user " + user.getFirstName()); // prints cassandra
        }

    }

此测试用例失败并打印Cassandra。

如果我做错了什么让我知道。

共有1个答案

段干开宇
2023-03-14
  • 使构造函数私有并为createInstance方法提供与构造函数或工厂方法相同的属性?有什么帮助?

答:使构造函数私有并提供createinstance()(工厂方法)本身没有帮助:这是您应该做的几件事之一,以便允许用户实际使用类及其实例,同时您仍然可以控制实例的创建方式。

  • Make attributes final-这篇文章没有解释这一点,我读了一些地方以避免意外修改。当没有mutator,类是final的时候,你怎么能意外地修改呢?将属性设置为final有什么帮助?
final public class SomeClass {
    final Integer i = 1;
}
class AnotherClass {

    public static void main (String[] args) throws Exception {

        SomeClass p = new SomeClass();
        Field i =p.getClass().getDeclaredField("i");
        i.setAccessible(true);
        i.set(p, 5);
        System.out.println("p.i = " + p.i); // prints 5
    }
}
    null

答:您可以使用builder模式或任何帮助您控制类实例创建的模式。

此外:
如果要确保类是不可变的,请确保任何getter返回类成员的深度副本。这种技术被称为“保护性/防御性复制”。你可以在这里阅读更多关于它的信息

 类似资料:
  • 我的目标是让Java对象不可变。我有一个班级< code >学生。为了实现不变性,我用以下方式对它进行了编码: 我的问题是,实现班级不变性的最佳方法是什么?

  • 问题内容: 在我的代码中,我正在创建一个对象集合,各个线程将以一种仅在对象是不可变的情况下才安全的方式访问这些对象。当试图将一个新对象插入到我的集合中时,我想测试一下它是否是不可变的(如果不是,我将抛出一个异常)。 我可以做的一件事是检查一些众所周知的不可变类型: 这实际上使我省了90%的路,但是有时我的用户会想要创建自己的简单不可变类型: 是否有某种方式(也许使用反射)可以可靠地检测到类是否不可

  • Kotlin有一个const关键字。但我不认为kotlin中的常数是我所认为的。这似乎与C中的const非常不同。在我看来,its仅适用于静态成员和Java中的原语,不针对类变量进行编译: 由于这似乎不起作用,我认为我真正想要的是第二个类,它删除我不想支持的操作: 这种方法的明显缺点是,我不能忘记更改这个类,以防我更改,这对我来说非常危险。 但是我不确定如何做到这一点。所以问题是:如何用意识形态静

  • 当一个包含不可移动的内容时,我不知道如何完美地转发它。

  • 问题内容: 代码段-1 代码段-2 我在第一个代码段中遇到了竞争。我知道这是因为我正在获得对不可变对象(类型为Integer)的锁定。 我已经写了第二个代码片段,这再次使“布尔”不变。但这有效(输出运行中不显示竞争条件)。如果我正确理解了上一个问题的解决方案,则以下是出现问题的一种可能方法 线程1锁定由指向的对象(例如A) 线程2现在试图获取由指向的对象的锁,并进入A的等待队列。 线程1进入同步块

  • 问题内容: Java中不变对象的优点显而易见: 一致状态 自动线程安全 简单 您可以通过使用私有final字段和构造函数注入来支持不变性。 但是,在Java中偏爱不可变对象有哪些弊端? 即 与ORM或Web演示工具不兼容? 不灵活的设计? 实施的复杂性? 是否可以设计一个主要使用不可变对象的大规模系统(深层对象图)? 问题答案: 但是,在Java中偏爱不可变对象有哪些弊端?与ORM或Web演示工具