Reputation: 4606
I need to implement a class in java where its field needs to be set only once, but it's value is not known at field declaration. To do so I have:
public class MyClass {
private String field1 = null;
public void setField1(String value) {
if (field1 == null) {
field1 = value;
}
}
}
However what I have do not prevent users to call setField1
more than once. That may lead to confusion where a user is trying to set it (without knowing it has been set somewhere else) and then the user will get confused by the field1
is not giving the value they set - until they go into the setField1
method to see what happened.
The other solution that I don't like is make a constructor to take into the value of field1
, and then provide no setter. Because it makes the class a lot harder to be extended, when multiple String fields are needed - in this approach, the constructor will need to take in a couple String
as parameters, and then the user can be so easily confused by/missing the parameters.
And apparently setting field1
as final
won't work either.
What should I do to prevent the issue I mentioned above?
Upvotes: 2
Views: 3201
Reputation: 59174
You should generally use the builder pattern for cases like this: https://en.wikipedia.org/wiki/Builder_pattern
MyClass instance = (new MyClassBuilder())
.setField1(...)
.setField2(...)
.build();
Your builder object lets you set all the fields and options you like, but the MyClass instance that it builds does not.
Upvotes: 4
Reputation: 100209
The common practice in such case is to throw a RuntimeException
. In your case IllegalStateException
suits best:
public void setField1(String value) {
if (field1 != null) {
throw new IllegalStateException("setField1 was already called");
}
field1 = Objects.requireNonNull(value);
}
Also note that it's better to check the passed string for null (I added Objects.requireNonNull
for this).
You cannot control this at compile time, because it's impossible to analyze program to say exactly whether the method called once or more without actually running the program.
Upvotes: 6