我是一个顽固的C ++粉丝,正在为Android应用程序挑选Java。在C ++中,创建和初始化对象的规范方法是在构造函数中完全初始化它:
class Message {
string payload;
int client;
// etc.
public:
Message(string payload, int client)
: payload(payload)
, client(client)
{}
};
这似乎可以用Java做。它有点丑陋,因为我想让某些成员const
(最好的Java可以做final
),但通常我可以弄明白。
但现在我正在运行FreeHEP-XDR
之类的库,其XDRSerializable
接口指定了签名:
void read(XDRDataInput in);
此函数将由Message
实现,显然不是静态实例化器,因为它返回void
。在调用此函数之前,Message
对象必须完全构造,可能使用默认构造函数。这困扰我:调用者可以轻松地在构造函数中传递XDRDataInput
,无论如何我将初始化对象两次(一次在默认构造函数中,再次在read
中)。最令人震惊的是,实现这一点需要我从某些final
数据成员中删除Message
修饰符,因为它们将在构造函数完成后被修改!
这是Java课程的标准吗?什么是对象保护,创建和初始化范例?
答案 0 :(得分:2)
嗯,构造函数的主要问题是它们不是多态的。这意味着调用此类构造函数的客户端需要始终知道她构建的具体类型。通过推迟初始化和构造,您可以在p点处决定要创建哪个具体实例,并在b点进行polimorfically初始化。
此外,java没有任何方法可以强制某个契约的实现者(一个接口,例如)来定义某个构造函数。所以它要么是为接口契约添加一个弱条件(比如javadoc中的注释说实现者应该提供一个接收XHRDataInput的构造函数),要么在接口中添加一个初始化方法,并强制你提供一个空构造函数(这是到目前为止,这是一种更常见的做法,可能是从JavaBeans“规范”继承而来的。
话虽如此,我也会说:是的,它完全打破了你的“最终”语义。您可以在“读取”方法中添加一个检查以检查某个条件,并确保您的对象只初始化一次(如果读取两次调用则抛出异常),但这完全取决于您。