Question

An interesting question came up today. Is it good practice to great a setter for a field that I know I will never need to re-set after the constructor?

P.S. I, of course, understand the reasons for using a private field and a getter vs. a public field, that makes sense, but should I really make a setter if I am not going to use it?

P.P.S. referring specifically to Java, although it shouldn't really matter what platform.

Was it helpful?

Solution

By not creating a setter and only allowing the field to be set through the constructor, you have created an immutable field. Once you create an instance of your class, that value will never change.

Note: The statement above will not hold if the value return by your getter is itself mutable. Say, if returning an instance of ArrayList, someone can use that reference to add and remove items in that list. Look at java.util.Collections.unmodifiableList to fix that. Even a java.util.Date can be changed if you return it in a getter. To fix that, you can use JodaTime (or other similar third-party date classes), or wait for Java 8.

In my humble (and other's not always so humble) opinion(s) imutability is a great thing that makes software less buggy and easier to maintain.

OTHER TIPS

It just depends.

If your class is part of an exported API and you have reason to believe that the clients of your API will have occasion to use a setter then it may make good sense to include one.

Here's the truth about getters and setters, though.

If your class has them, then your class is mutable. Mutable data and mutable objects are what they are. If your design intent specifies that this API will always be single-threaded, then you have no problems.

However, even in single-threaded apps, you should aspire to create immutable objects wherever possible. The downside to immutable objects is that there is no role for getters and setters in them (** see note).

A compromise is the Builder Pattern (Bloch, et al. Effective Java 2nd Ed.). In this patters, you use a mutable helper object to set the fields for your object ... and then when you're ready, your helper object uses the data you've set to create an immutable instance of the object you want.

Use mutable objects when your needs are simple and there's no concerns over contention or concurrency. But remember, the more mutable your object is, the harder it is to reason about its state. And the harder it is to reason about its state, the potentially more difficult it is to enforce invariants and maintain security. An object that can have only one state solves almost all of these problems. Especially if your class is a value class, you should try to create immutable objects when you can.

(**) note: it is, of course, possible to have setters for an immutable class. In such a case, the setter instantiates a new, immutable object, thus preserving its immutability. The String class relies upon this strategy.

Is it good practice to create a setter for a field that I know I will never need to re-set after the constructor?

If you know this in advance, then, by all means, write it in your code. Make that field final, and then you won't have any doubts, as the compiler itself won't let you define a setter.

This avoids writing a method "because it may be expected", and is also a step forward in keeping the code clean and verifiable, in my opinion. You're declaring things just as they are, which also eliminates the need to test the immutability of the value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top