在基于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;
}
当用户登录时,将为他创建会话对象,并为他设置userId
、name
和Account
。
之后,每个程序员都可以访问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中复制对象
- 对象复制