Java中的对象创建/初始化语义 我是一个死硬派的C++迷,正在为Android应用程序挑选java。在C++中,创建和初始化对象的规范方式将在构造函数中完全初始化: class Message { string payload; int client; // etc. public: Message(string payload, int client) : payload(payload) , client(client) {} };

Java中的对象创建/初始化语义 我是一个死硬派的C++迷,正在为Android应用程序挑选java。在C++中,创建和初始化对象的规范方式将在构造函数中完全初始化: class Message { string payload; int client; // etc. public: Message(string payload, int client) : payload(payload) , client(client) {} };,java,object,Java,Object,在Java中似乎可以做到这一点。它变得有点难看,因为我想让某些成员const(Java能做的最好的事情是final),但一般来说我能弄明白 但是现在我正在运行一些库,比如FreeHEP XDR,它们的xdrseriable接口指定了一个签名: void read(XDRDataInput in); 此函数将由消息实现,它显然不是静态实例化器,因为它返回void。调用此函数之前,必须完全构造消息对象,可能使用默认构造函数。这让我很烦恼:调用者可以很容易地在构造函数中传递一个XDRDataInpu

在Java中似乎可以做到这一点。它变得有点难看,因为我想让某些成员
const
(Java能做的最好的事情是
final
),但一般来说我能弄明白

但是现在我正在运行一些库,比如
FreeHEP XDR
,它们的
xdrseriable
接口指定了一个签名:

void read(XDRDataInput in);
此函数将由
消息
实现,它显然不是静态实例化器,因为它返回
void
。调用此函数之前,必须完全构造
消息
对象,可能使用默认构造函数。这让我很烦恼:调用者可以很容易地在构造函数中传递一个
XDRDataInput
,无论如何,我将初始化对象两次(一次在默认构造函数中,另一次在
read
中)。最糟糕的是,实现这一点需要我从某些
消息
数据成员中删除我的
final
修饰符,因为它们将在构造函数完成后被修改


这是java课程的标准吗?什么是对象保护、创建和初始化范例?

好吧,构造函数的主要问题是它们不是多态的。这意味着调用此类构造函数的客户机需要始终知道她所构建的具体类型。通过延迟初始化和构造,您可以主动决定在点a创建哪个具体实例,并在点b进行政治初始化

而且,java没有任何方法强制特定契约(例如,接口)的实现者定义特定的构造函数。因此,它要么向接口契约中添加一个弱条件(比如javadoc中的一条注释说,实现者应该提供一个接收XHRDataInput的构造函数),要么向接口中添加一个初始化方法,并强制您提供一个空构造函数(到目前为止,这是一种更常见的实践,可能是从JavaBeans“规范”继承而来的)


话虽如此,我还是要声明:是的,它完全破坏了“final”语义。您可以在“read”方法中添加一个检查,检查特定条件,并确保对象只初始化一次(如果read被调用两次,则引发异常),但这完全取决于您。

XDRDataInput是一个指针。当然,但我调用它的对象必须在调用之前进行初始化。成员的初始值将被
read
。我不关心创建另一个
XDRDataInput
。我正在实现的函数将是
Message.read(XDRDataInput in)
消息
必须在调用
read
之前进行初始化。这是不是抱怨api强迫您创建一个可变对象,而您希望它是不可变的?我认为api设计人员犯错误的空间很大。但是如果您想使用他们的api,您必须遵守他们的规则。以下解释n很有意义,谢谢。不过,现在我的代码中加入了一些小的getter,
final public
成员可以很好地工作。呃,Java。这可能是我们完全避免使用公共字段的原因之一。