从javabean创建不可变对象
我参与了这个项目,在这个项目中,我们是在很好的遗留代码的基础上构建的。我有一个关于一个大JavaBean对象的特殊情况,它必须通过有线传输。因此,我的第一个想法是使其不可变并可序列化,以实现这一点。在这一点上,我面临着一些困难的选择:-从javabean创建不可变对象,java,immutability,javabeans,Java,Immutability,Javabeans,我参与了这个项目,在这个项目中,我们是在很好的遗留代码的基础上构建的。我有一个关于一个大JavaBean对象的特殊情况,它必须通过有线传输。因此,我的第一个想法是使其不可变并可序列化,以实现这一点。在这一点上,我面临着一些困难的选择:- 理想情况下,我想有办法 自动生成一个不可变的, 此类的可序列化版本。 我没有重构或修改的余地 以任何方式改变这个类,我 我真的很不愿意 复制并粘贴带有 不同的名字 假设我放弃了1,即i 实际上选择了复制的代码 巨大的javabean类,我仍然 将处于不利的境地
感谢和问候,要使其真正不可变,您需要在构造时初始化成员 要做到这一点并避免构造函数中出现大量参数列表,一种方法(我不是说它很漂亮!)是使用具有相同属性的可变类型。通过“setters”一次设置一个可变类型的属性,然后将可变对象作为单个参数传递给不可变类型的构造函数。然后,不可变对象将属性从可变源复制到它自己的(
final
)成员
你也可以考虑“有效的不可改变性”。也就是说,即使系统没有强制执行不可变性,您也可以使用将初始化阶段与使用阶段明确分开的编码实践。毕竟,序列化不需要不变性
您可以更进一步,为接口创建一个实现隐藏包装器,该包装器不公开实现的属性。包装器仅通过委托给“真实”实现来实现接口中的方法。包装器中不存在来自实现的setter和getter。这将阻止客户端简单地从接口向下转换到实现类,并操纵属性。20-25属性对于一次性来说并不庞大,特别是如果您使用的是一个半体面的编辑器 如果在构造不可变版本时已经有一个可变实例,只需将其传递给构造函数即可 如果您想成为真正邪恶的黑客,请使用
java.beans
为实现Externalizable
的可变类或子类创建可序列化的Map
。或者,您可以使用java.beans
XML序列化(通过java序列化可以发送的XML…。步骤1:创建一个新类,并为其提供与“大JavaBean对象”的实例变量名称完全相同的实例变量。这个新类不应该有setter(但只有getter)使其不可变
步骤2:使用Apache Commons BeanUtils.copyProperties将所有属性(即实例变量)从“大java bean对象”复制到新对象。一些想法:
受保护的设置器和工厂方法
您可以使用受保护的setter方法定义bean,并在同一个包中定义一个接受所有参数并调用这些setter的工厂类。bean在该包之外是不可变的。为了实现这一点,请确保密封jar,以便最终用户无法在同一个包中创建新类
注意:您可以使用my JavaDude Bean注释简化创建:
例如:
@Bean(writer=Access.PROTECTED, // all setXXX methods will be protected
properties={
@Property(name="name"),
@Property(name="age", type=int.class)
})
public class Person extends PersonGen {
}
在eclipse中创建getter和构造函数
Eclipse提供了一些很好的工具来加快速度:
一个包含getter的简单只读接口怎么样 如果bean类是您自己的,那么让它简单地实现接口,并在创建后仅使用接口
如果您无法控制bean类,还可以创建一个getter接口,并通过为getter接口创建一个代理来实现它,该代理使用一个调用处理程序将所有方法调用委托给bean。您可以为每个场景添加一些代码示例吗,我正在努力理解,这是一个很好的问题。除非您有一个重复的不可变类,否则似乎没有真正好的方法来解决这个问题。我使用了有效的不可变方法!