Defining your own IMHO exception is not a big deal, especially if it extends a RuntimeException . Therefore, I suggest you define a ValueAlreadySetException extends IllegalStateException and use it.
The next point is the logic in each setter, which you should duplicate as suggested by @Renan. I offer you the following. Define a special generic container and use it:
public class SetOnceContainer<T> { private Class<T> type; private String name; private T value; private boolean set = false; public SetOnceContainer(Class<T> type, String name) { this.type = type; this.name = name; } public void set(T value) { if (set) { throw new ValueAlreadySetException(name); } this.value = value; this.set = true; } public T get() { return value; } }
Note that this implementation supports null values.
Now you can use it as:
public MyClass { private SetOnceContainer<Integer> number = new SetOnceContainer<Integer>(Integer.class, "number"); private SetOnceContainer<String> text = new SetOnceContainer<String>(String.class, "text"); public void setNumber(int value) { number.set(value); } public void setText(String value) { text.set(value); } public Integer getNumber() { return number.get(); } public String getText() { text.get(); } }
Implementation is encapsulated at one time. You can change it in one place if you need. Null values ββare also supported. Settings and getters are a bit more complicated than regular ones.
Alexr source share