我正在使用GWT并且被限制为具有零参数构造函数。 这意味着我在每个类上使用静态工厂方法来设置成员变量:
public class Point {
private final float x;
private final float y;
public static Point build(float x, float y) {
Point p = new Point();
p.x = x;
p.y = y;
return p;
}
// getters for x and y
// other methods...
}
现在问题是x和y不能是final,因为我将它们设置在构造函数之外,但理想情况下我希望它们是不可变的。
最好的方法是什么?
答案 0 :(得分:3)
让语言尽可能多地执行程序属性是一个好主意,并且使用final
关键字肯定是一种很好的做法。但是这种情况下final
关键字过于严格,无法使GWT的序列化机制起作用,至少在当前状态下是这样。因此,你遗憾地无法使用这个功能。
但我认为值得一提的是,如果你不为x和y提供setter并保留它们private
,那么你的类确实是不可变的。这不是强制执行此操作的语言,而是您的代码。
答案 1 :(得分:2)
该类只需要一个空构造函数来支持序列化。您也可以使用其他构造函数,因此您不需要工厂方法。这就是说你不能拥有最终变量,因为需要零参数构造函数。
希望这将在以后的版本中进行整理(参见http://code.google.com/p/google-web-toolkit/issues/detail?id=1054)
答案 2 :(得分:0)
你真的被限制为零参数构造函数吗?可能有一种方法告诉GWT您想要使用带有参数的构造函数。无论如何,Waldheinz的建议与我建议的一样。
但另一件需要考虑的事情是,GWT将使用这个默认的constrcutor在某个时刻创建这个类的实例。因此,如果您的类依赖于这两个实例字段来获得可能导致错误的有效值。
答案 3 :(得分:0)
如果您的零arg构造函数约束仅仅是因为GWT-RPC,那么您可以使用自定义字段序列化器来克服这个问题:它必须是同一个包中的一个类,命名相同作为要序列化的类但具有_CustomFieldSerializer
后缀并扩展CustomFieldSerializer
您可以关注the java.lang.Boolean
custom field serializer作为示例。在你的情况下,这应该工作:
public final class Point_CustomFieldSerializer extends CustomFieldSerializer<Point> {
@Override
public boolean hasCustomInstantiateInstance() { return true; }
@Override
public Point instantiateInstance(SerializationStreamReader streamReader) throws SerializationException {
return new Point(streamReader.readInt(), streamReader.readInt());
}
@Override
public void deserializeInstance(SerializationStreamReader streamReader, Point instance) throws SerializationException {
// everything is done in instantiateInstance
}
@Override
public void serializeInstance(SerializationStreamWriter streamWriter, Point instance) throws SerializationException {
streamWriter.writeInt(instance.getX());
streamWriter.writeInt(instance.getY());
}
}