Java 在特定操作后创建不可变对象
我是Java新手,所以我想知道是否可以这样做? 我有一个document对象,比如document doc1。。一旦我使用jdom构建器构建这个对象,我就不希望它被改变。。此外,它还需要始终可用。。我相信后者可以通过使用static关键字来实现。。如何确保一旦使用jdom构建器,就没有人可以修改这个对象?因此,在下面的示例中,类中的声明应该是什么,以确保在使用builder构建templateDocument后不能修改它Java 在特定操作后创建不可变对象,java,Java,我是Java新手,所以我想知道是否可以这样做? 我有一个document对象,比如document doc1。。一旦我使用jdom构建器构建这个对象,我就不希望它被改变。。此外,它还需要始终可用。。我相信后者可以通过使用static关键字来实现。。如何确保一旦使用jdom构建器,就没有人可以修改这个对象?因此,在下面的示例中,类中的声明应该是什么,以确保在使用builder构建templateDocument后不能修改它 public static void createDocumentFrom
public static void createDocumentFromTemplate(StatusBuffer statusBuffer)
{
//templateDocument = new Document();
SAXBuilder builder = new SAXBuilder();
Reader input = new StringReader(statusBuffer.toString());
try {
templateDocument = builder.build(input);
} catch (JDOMException e) {
final String message = "Error in building xml from output template";
LOG.error(message, e);
} catch (IOException e) {
final String message = "Error in accessing output file template";
LOG.error(message, e);
}
您可以声明templateDocument
final
,这将阻止任何人重新分配引用。但是,这不会阻止他们设置templateDocument的成员字段。因此,如果templateDocument有一些您以前分配的成员字段,并且为该字段定义了一个公共setter,那么该字段仍然可以重新分配。创建singleton工厂是否满足您的需要?封装工厂中延迟实例化的实例
因为工厂的客户端被阻止访问实例,所以不需要将其标记为final。工厂本身可能是最终的。从调用builder.build()获得的org.jdom.Document是可变的。您可以将templateDocument设置为final,但这只会阻止您将另一个org.jdom.Document重新分配给它。您仍然可以调用templateDocument.removeContent(),或者在文档中查找元素并删除其子元素 所以简单的答案是不,你不能让它一成不变 理论上,您可以创建自己的不可变类来镜像JDOM类,然后从org.JDOM对应的类中费力地初始化它们,但这将是一项非常艰巨的工作 如果您只是试图检测文档中的错误突变,而它不是非常大,那么在调用builder.build()之后,您可以立即将文档序列化回XML字符串,并将其存储在变量中。代码运行后,可以将文档的最终状态序列化为另一个XML字符串,并比较这两个字符串以确保未进行任何更改 如果这样做成本太高(无论是在性能上还是在内存上,或者两者兼而有之),您可以将此比较代码置于调试模式(例如,使用Java断言)。您还可以编写JUnit单元测试并将比较代码放入其中
这个主题的一个变体是获取初始XML字符串和最终XML字符串的128位散列值,并比较它们,而不是实际的XML字符串。这样就不必存储初始字符串。是的,我可以这样做。。但我希望这个对象在执行过程中保持不变。。所以我不能在方法中本地声明它,如果我在类中声明它,编译器会抱怨它没有初始化,如果初始化为null,我就不能执行builder.build(in)。。那么,在builder.build步骤完成后,如何创建一个对象并使其成为最终对象呢?我不希望任何人在builder.build(in)之后修改它?您需要做的是在create内部声明一个最终的局部变量,并将调用templateDocument的最终成员字段设置为该方法调用的结果。