4

I'm a die-hard C++ fan who is picking up Java for Android apps. In C++, the canonical way of creating and initializing an object would be to totally intialize it in the constructor:

class Message {
  string payload;
  int client;
  // etc.

public:
  Message(string payload, int client)
    : payload(payload)
    , client(client)
  {}
};

This seems possible to do in Java. It gets a bit uglier because I want to make certain members const (the best Java can do is final), but generally I can figure it out.

But now I'm running across libraries such as FreeHEP-XDR, whose XDRSerializable interface specifies a signature:

void read(XDRDataInput in);

This function, which will be implemented by Message, is obviously not a static instantiator, as it returns void. The Message object would have to be fully constructed, probably with a default constructor, before calling this function. This bothers me: the caller can easily pass an XDRDataInput in the constructor, and anyway I'll be initializing the object twice (once in the default constructor, again in read). Most egregiously, implementing this requires me to drop my final modifier from certain Message data members, because they'll be modified after the constructor is finished!

Is this par for the course for Java? What's the object protection, creation, and initialization paradigm?

14
  • XDRDataInput is a pointer. Commented May 28, 2014 at 4:04
  • Sure, but the object I'm calling it on would have to be initialized before the call. The members' initial values will then be clobbered by read. Commented May 28, 2014 at 4:05
  • I'm not concerned about creating another XDRDataInput. The function I'm implementing would be Message.read(XDRDataInput in). The Message must be initialized before calling read. Commented May 28, 2014 at 4:09
  • 1
    is this a complaint that the api is forcing you to make a mutable object when you'd rather it be immutable? Commented May 28, 2014 at 4:26
  • 1
    i think there's just a lot of room for api designers to go wrong. but if you want to use their api you're stuck with following their rules. Commented May 28, 2014 at 4:37

1 Answer 1

2

Well, the main issue with constructors is that they are not polymorphic. Meaning that the client whose invoking such constructors needs to always know what concrete type is she building. By deferring initialization and construction you can, pontentially, take the decision of which concrete instance you want to create at point a and polimorfically initialize it at point b.

Also, java does not have any way to force implementors of a certain contract (an interface, by example) to define a certain constructor. So it is either adding a weak condition to the interface contract (like a comment in the javadoc saying that implementors should provide a constructor that receives XHRDataInput) or adding a initialization method to the interface and forcing you to provide an empty constructor instead (which is by far a more common practice, probably inherited from the JavaBeans "specification").

Having said that I will also state: Yes it totally breaks your "final" semantics. You can add a check in your "read" method that checks over a certain condition and ensure that your object is initialized only once (throwing an Exception if read is invoked twice), but that is totally up to you.

Sign up to request clarification or add additional context in comments.

2 Comments

This explanation makes a lot of sense, thanks. Although, now I get to have little getters sprinkled in my code where final public members would have worked fine. Eh, Java.
That is probably one reason why we avoid public fields at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.