在Java中使会话中的对象不可变



在基于web的应用程序中,我们在session中为每个登录用户都有一个User对象。

用户如下

Class User {
    //With setter and getters
      private String userId,
      private String name,
      private Account Account,
 }
Class Account {
     //with setter and getters.
     private String accountNumber;    
 }

当用户登录时,将为他创建会话对象,并为他设置userIdnameAccount

之后,每个程序员都可以访问session并读取用户及其信息。但也有可能是一个程序员错误地更改了Account

例如:

 1. TrasnferVO = new TransferVO;
 2. TransferVO.setAccount( user.getAccount() );
 3. TransferVO.getAccount.setAccountNumber("foo");
 4. User user = getUserFromSession();
 5. user.getAccountNumber(); // Now I have foo

2行,应创建用户帐户的新副本并将其设置为TransferVO,因为传递的对象引用不是其值!因此,3行将更改用户会话帐号。我们将在会话中丢失损坏的accountNumber

是否有任何指导方针来处理它,或者每个程序员都必须处理它。

当然,这个错误可能发生在项目中的每一个代码中,但我正在寻找一种方法来使会话对象属性不可变,这是非常重要的。

问题中的情况不清楚。

使对象不可变

要在Java中创建一个不可变对象,有两种方法:

  • 封装:将成员标记为private,定义一个不带setter方法的接口,并在类上实现该接口。将对象作为只读接口的实例传递给会话
  • 将成员标记为final。成员只能被指定一次对对象(或基本体值)的引用。标记为final的成员不能重新分配

请记住,在以上任何一种情况下,分配给成员的对象本身都可能是可修改的。在上述两种情况下,将对象分配给类的成员是我们要保护的,但修改分配对象自己的内部成员是一个单独的问题。

复制对象

或者,您可以制作一个对象的副本,然后继续对克隆进行修改。也许这最适合你的情况。

了解标记接口Cloneable以及用public方法重写protected Object::clone方法。读取:

  • 如何在Java中复制对象
  • 对象复制

最新更新