What's the proper way to ensure a value only gets set once, although the time it will be set is unknown (ie: not in the constructor). I could do a null check or keep track of a flag and throw an exception - but what exception should I throw? It's for a small, localized library and I prefer not to create my own ValueAlreadyAssigned exception for such a seemingly generic case.
In the setter. Do it like this:
private foo bar;
public void setFoo(foo bar) {
if (this.bar == null) {
this.bar = bar;
} else {
System.out.println("Don't touch me!");
// J/K Throw an IllegalStateException as Michal Borek said in his answer.
}
}
The method could throw IllegalStateException, since it's javadocs say:
Signals that a method has been invoked at an illegal inappropriate
time.
IMHO definition of your own exception is not a big deal especially if it extends RuntimeException. So I'd suggest you to define ValueAlreadySetException extends IllegalStateException and use it.
The next point is the logic into each setter you have to duplicate according to #Renan's suggestion. I'd suggest you the following. Define 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;
}
}
Please pay attention that this implementation supports null values too.
Now you can use it as following:
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();
}
}
The implementation is encapsulated into once point. You can change it in once place if you need. Null values are supported too. The setters and getters are just a little bit more complicated than regular.
Related
I have two Enums as below
public enum Read {
PRIVATE (1), PUBLIC(2);
private final int value;
Read(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
And
public enum Write {
CREATE (1), UPDATE(2);
private final int value;
Write(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
Both enum needing some values to represent them. Is there a way for us to share the code, where the Read and Write "extends" from something that has value, instead of for every enum, I need to have getValue, value etc? Probably one way is to make a class, but thinking if we could make Enum "extensible"?
Don't fight it; embrace classes.
Enumerations generally represent some form of state; that is, each enum value has a specific business-associated state with it. You'd have to decide what Read.PRIVATE and Read.PUBLIC truly represented, but they're still states. The same is true of Write.CREATE and Write.UPDATE.
The real question now becomes, how do these two enums relate to one another? They likely don't, given that reading something is independent and severable from writing something.
In this instance, I'd probably represent it in a class:
public class Permission {
private Read readState;
private Write writeState;
public void setReadState(Read readState) {
this.readState = readState;
}
public void setWriteState(Write writeState) {
this.writeState = writeState;
}
}
It's unclear what the values would represent, since the enums are guaranteed unique, but take from this what you will.
You could use EnumSet to hold permissions like this:
Permission:
public enum Permission {
READ_PRIVATE, READ_PUBLIC, WRITE_CREATE, WRITE_UPDATE;
}
User:
public class User {
private final EnumSet<Permission> permissions;
public User(Permission... permissions) {
this.permissions = EnumSet.copyOf(Arrays.asList(permissions));
}
public boolean hasPermission(Permission permission) {
return permissions.contains(permission);
}
public void addPermisssion(Permission p) {
permissions.add(p);
}
public void removePermisssion(Permission p) {
permissions.remove(p);
}
}
Usage:
User user = new User(Permission.READ_PRIVATE, Permission.WRITE_UPDATE);
if ( user.hasPermission(Permission.WRITE_UPDATE) )
{
//do something...
}
I have some class storing keys with important information. No one else is allowed to create a key, since a key relys on static information (like certain directory structures etc.).
public final class KeyConstants
{
private KeyConstants()
{
// could throw an exception to prevent instantiation
}
public static final Key<MyClass> MY_CLASS_DATA = new Key<MyClass>("someId", MyClass.class);
public static class Key<T>
{
public final String ID;
public final Class<T> CLAZZ;
private Key(String id, Class<T> clazz)
{
this.ID = id;
this.CLAZZ = clazz;
}
}
}
This example is simplyfied.
I wanted to test the consequences of a wrong key (exception handling, etc.) and instantiated the class via reflection in a JUnit test case.
Constructor<?> c = KeyConstants.Key.class.getDeclaredConstructor(String.class, Class.class);
c.setAccessible(true);
#SuppressWarnings ("unchecked")
KeyConstants.Key<MyClass> r = (KeyConstants.Key<MyClass>) c.newInstance("wrongId", MyClass.class);
Then I asked myself how could I prevent further instantiation of the key class (i. e. preventing further object creating via reflection)?
enums came to my mind, but they don't work with generics.
public enum Key<T>
{
//... Syntax error, enum declaration cannot have type parameters
}
So how can I keep a set of n instances of a generic class and prevent further instantiation?
So how can I keep a set of n instances of a generic class and prevent
further instantiation?
If you truly want to use this pattern, then no one (including you) should be able to instantiate a Key object. In order to keep a set of n instances in a class with this pattern, you could have a private constructor, a static method for access and a SecurityManager to prevent reflection. And since you want to be able to access the keys as pubic constants, I would try something like this..
public class KeyConstants{
// Here are your n instances for public access
public static final int KEY_1 = 1;
public static final int KEY_2 = 2;
.
.
.
public static final int KEY_N = 'n';
// now you can call this method like this..
// Key mKey = KeyConstants.getKey(KeyConstants.KEY_1);
public static Key getKey(int key){
List keys = Key.getInstances();
switch(key){
case KEY_1:
return keys.get(0);
case KEY_2:
return keys.get(1);
.
.
.
case KEY_N:
return keys.get(n);
default:
// not index out of bounds.. this means
// they didn't use a constant
throw new IllegalArgumentException();
}
}
static class Key<T>{
private static List<Key> instances;
private String ID;
private Class<T> CLAZZ;
private Key(String id, Class<T> clazz){
this.ID = id;
this.CLAZZ = clazz;
}
public static List<Key> getInstances(){
if(instances == null){
instances = new ArrayList<Key>();
//populate instances list
}
return instances;
}
}
}
Use SecurityManager to prevent reflection access.
//attempt to set your own security manager to prevent reflection
try {
System.setSecurityManager(new MySecurityManager());
} catch (SecurityException se) {
}
class MySecurityManager extends SecurityManager {
public void checkPermission(Permission perm) {
if (perm.getName().equals("suppressAccessChecks"))
throw new SecurityException("Invalid Access");
}
}
This will throw a SecurityException anytime someone attempts to access a private variable or field in your class (including access attempts via reflection).
I'm not sure I fully understand your question, but if a private constructor is not sufficient, can you use a more dynamic approach and throw an exception in the constructor after a signal is given? For example:
public static class Key<T>
{
private static boolean isLocked = false;
// Call this method when you want no more keys to be created
public static void lock() { isLocked = true; }
...
private Key(String id, Class<T> clazz)
{
if (isLocked) throw new IllegalStateException("Cannot create instances of Key");
this.ID = id;
this.CLAZZ = clazz;
}
}
Then - and this is the disadvantage - you will have to call Key.lock() once you want to prevent more instances being created.
As you showed in your code to prevent instantiating KeyConstants you can throw some Exception inside private-non-argument constructor.
Harder part is way to block creating KeyConstants.Key constructor from outside of KeyConstants class.
Some wild idea
Maybe create Exception in your constructor and check how its stack trace looks like. When I add this code to constructor
private Key(String id, Class<T> clazz) {
StackTraceElement[] stack = new Exception().getStackTrace();
for (int i=0; i<stack.length; i++){
System.out.println(i+") "+stack[i]);
}
this.ID = id;
this.CLAZZ = clazz;
}
and create instance of Key with reflection like
Constructor<?> c = KeyConstants.Key.class.getDeclaredConstructor(
String.class, Class.class);
c.setAccessible(true);
KeyConstants.Key<MyClass> r = (KeyConstants.Key<MyClass>) c
.newInstance("wrongId", MyClass.class);
I get
0) KeyConstants$Key.<init>(Test.java:38)
1) sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
2) sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
3) sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
4) java.lang.reflect.Constructor.newInstance(Constructor.java:525)
so maybe just if 4th element of stack is java.lang.reflect.Constructor.newInstance throw Exception to prevent executing rest of constructors code like:
if (stack.length>=4 && stack[4].toString().startsWith("java.lang.reflect.Constructor.newInstance")){
throw new RuntimeException("cant create object with reflection");
}
I came across some Multiton patterns recently, where I tried to handle problems with unique enum keys, that gave me the idea of another approach.
The keys can be used for information flow as I intended, or even as keys for typesafe heterogeneous container, where they can perform compile-time casting.
Key-defining class
public class KeyConstants
{
public static final KeysForIntegers SOME_INT_KEY = KeysForIntegers.KEY_2;
public static final KeysForStrings SOME_STRING_KEY = KeysForStrings.KEY_1;
public interface Key<Type>
{
public Class<Type> getType();
}
/* Define methods that classes working with the keys expect from them */
public interface KeyInformation
{
public String getInfo1();
// and so on...
}
public enum KeysForStrings implements Key<String>, KeyInformation
{
KEY_1("someId");
public final String ID;
private KeysForStrings(String id)
{
ID = id;
}
#Override
public String getInfo1()
{
return "Good piece of information on " + ID + ".";
}
#Override
public Class<String> getType()
{
return String.class;
}
}
public enum KeysForIntegers implements Key<Integer>, KeyInformation
{
KEY_2("bla");
public final String ID;
private KeysForIntegers(String id)
{
this.ID = id;
}
#Override
public String getInfo1()
{
return "Some info on " + ID + ".";
}
#Override
public Class<Integer> getType()
{
return Integer.class;
}
}
}
Example key-using class
public class KeyUser
{
public static void main(String[] args)
{
KeysForIntegers k1 = KeyConstants.SOME_INT_KEY;
KeysForStrings k2 = KeyConstants.SOME_STRING_KEY;
processStringKey(k2);
useIntKey(k1);
Integer i = useIntKey(KeyConstants.SOME_INT_KEY);
processStringKey(KeyConstants.SOME_STRING_KEY);
}
/* My methods should just work with my keys */
#SuppressWarnings ("unchecked")
public static <TYPE, KEY extends Enum<KeysForIntegers> & Key<TYPE> & KeyInformation> TYPE useIntKey(KEY k)
{
System.out.println(k.getInfo1());
return (TYPE) new Object();
}
public static <KEY extends Enum<KeysForStrings> & KeyInformation> void processStringKey(KEY k)
{
System.out.println(k.getInfo1());
// process stuff
}
}
I have another approach, you can bound an interface in a way to only be implemented by enum.
With that approach you have a fixed set of instances at compile time.
If you want to add lazy loading, the enums implementing it should be proxies that load the desired object if it is requested. The class or classes that are hidden behind the proxies should only be visible to them, so that they have exclusive access to the constructor.
public class User {
public static <S> S handleKey(FixedInstanceSet<S,?> key) {
return key.getKey();
}
}
interface FixedInstanceSet<S, T extends Enum<T> & FixedInstanceSet<S,T>>
{
public S getKey();
}
enum StringKeys implements FixedInstanceSet<String, StringKeys> {
TOP, DOWN, LEFT, RIGHT;
#Override
public String getKey() { return null; }
}
enum IntKeys implements FixedInstanceSet<Integer, IntKeys > {
TOP, DOWN, LEFT, RIGHT;
#Override
public Integer getKey() { return null; }
}
/*
* Bound mismatch: The type NotWorking is not a valid substitute for the bounded
* parameter <T extends Enum<T> & FixedInstanceSet<S,T>> of the type
* FixedInstanceSet<S,T>
*/
//class NotCompiling implements FixedInstanceSet<String, NotCompiling> {
//
// #Override
// public String getKey() { return null; }
//}
If I understand you correctly, you don't want your class to be instantiated.
You can set the default constructor to private
private Key() throws IllegalStateException //handle default constructor
{
throw new IllegalStateException();
}
This will prevent its improper instantiation.
Update:
added throw IllegalStateException
I want a class that I can create instances of with one variable unset (the id), then initialise this variable later, and have it immutable after initialisation. Effectively, I'd like a final variable that I can initialise outside of the constructor.
Currently, I'm improvising this with a setter that throws an Exception as follows:
public class Example {
private long id = 0;
// Constructors and other variables and methods deleted for clarity
public long getId() {
return id;
}
public void setId(long id) throws Exception {
if ( this.id == 0 ) {
this.id = id;
} else {
throw new Exception("Can't change id once set");
}
}
}
Is this a good way of going about what I'm trying to do? I feel like I should be able to set something as immutable after it's initialised, or that there is a pattern I can use to make this more elegant.
Let me suggest you a little bit more elegant decision.
First variant (without throwing an exception):
public class Example {
private Long id;
// Constructors and other variables and methods deleted for clarity
public long getId() {
return id;
}
public void setId(long id) {
this.id = this.id == null ? id : this.id;
}
}
Second variant (with throwing an exception):
public void setId(long id) {
this.id = this.id == null ? id : throw_();
}
public int throw_() {
throw new RuntimeException("id is already set");
}
The "set only once" requirement feels a bit arbitrary. I'm fairly certain what you're looking for is a class that transitions permanently from uninitialized to initialized state. After all, it may be convenient to set an object's id more than once (via code reuse or whatever), as long as the id is not allowed to change after the object is "built".
One fairly reasonable pattern is to keep track of this "built" state in a separate field:
public final class Example {
private long id;
private boolean isBuilt;
public long getId() {
return id;
}
public void setId(long id) {
if (isBuilt) throw new IllegalArgumentException("already built");
this.id = id;
}
public void build() {
isBuilt = true;
}
}
Usage:
Example e = new Example();
// do lots of stuff
e.setId(12345L);
e.build();
// at this point, e is immutable
With this pattern, you construct the object, set its values (as many times as is convenient), and then call build() to "immutify" it.
There are several advantages to this pattern over your initial approach:
There are no magic values used to represent uninitialized fields. For example, 0 is just as valid an id as any other long value.
Setters have a consistent behavior. Before build() is called, they work. After build() is called, they throw, regardless of what values you pass. (Note the use of unchecked exceptions for convenience).
The class is marked final, otherwise a developer could extend your class and override the setters.
But this approach has a fairly big drawback: developers using this class can't know, at compile time, if a particular object has been initialized or not. Sure, you could add an isBuilt() method so developers can check, at runtime, if the object is initialized, but it would be so much more convenient to know this information at compile time. For that, you could use the builder pattern:
public final class Example {
private final long id;
public Example(long id) {
this.id = id;
}
public long getId() {
return id;
}
public static class Builder {
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Example build() {
return new Example(id);
}
}
}
Usage:
Example.Builder builder = new Example.Builder();
builder.setId(12345L);
Example e = builder.build();
This is much better for several reasons:
We're using final fields, so both the compiler and developers know these values cannot be changed.
The distinction between initialized and uninitialized forms of the object is described via Java's type system. There is simply no setter to call on the object once it has been built.
Instances of the built class are guaranteed thread safe.
Yes, it's a bit more complicated to maintain, but IMHO the benefits outweigh the cost.
I recently had this problem when writing some code to construct an immutable cyclic graph where edges reference their nodes. I also noticed that none of the existing answers to this question are thread-safe (which actually allows the field to be set more than once), so I thought that I would contribute my answer. Basically, I just created a wrapper class called FinalReference which wraps an AtomicReference and leverages AtomicReference's compareAndSet() method. By calling compareAndSet(null, newValue), you can ensure that a new value is set at most once by multiple concurrently modifying threads. The call is atomic and will only succeed if the existing value is null. See the example source below for FinalReference and the Github link for sample test code to demonstrate correctness.
public final class FinalReference<T> {
private final AtomicReference<T> reference = new AtomicReference<T>();
public FinalReference() {
}
public void set(T value) {
this.reference.compareAndSet(null, value);
}
public T get() {
return this.reference.get();
}
}
Google's Guava library (which I recommend very highly) comes with a class that solves this problem very well: SettableFuture. This provides the set-once semantics that you ask about, but also a lot more:
The ability to communicate an exception instead (the setException method);
The ability to cancel the event explicitly;
The ability to register listeners that will be notified when the value is set, an exception is notified or the future is canceled (the ListenableFuture interface).
The Future family of types in general used for synchronization between threads in multithreaded programs, so SettableFuture plays very nicely with these.
Java 8 also has its own version of this: CompletableFuture.
You can simply add a boolean flag, and in your setId(), set/check the boolean. If I understood the question right, we don't need any complex structure/pattern here. How about this:
public class Example {
private long id = 0;
private boolean touched = false;
// Constructors and other variables and methods deleted for clarity
public long getId() {
return id;
}
public void setId(long id) throws Exception {
if ( !touchted ) {
this.id = id;
touched = true;
} else {
throw new Exception("Can't change id once set");
}
}
}
in this way, if you setId(0l); it thinks that the ID is set too. You can change if it is not right for your business logic requirement.
not edited it in an IDE, sorry for the typo/format problem, if there was...
Here's the solution I came up with based on mixing some of the answers and comments above, particularly one from #KatjaChristiansen on using assert.
public class Example {
private long id = 0L;
private boolean idSet = false;
public long getId() {
return id;
}
public void setId(long id) {
// setId should not be changed after being set for the first time.
assert ( !idSet ) : "Can't change id from " + this.id + " to " + id;
this.id = id;
idSet = true;
}
public boolean isIdSet() {
return idSet;
}
}
At the end of the day, I suspect that my need for this is an indication of poor design decisions elsewhere, and I should rather find a way of creating the object only when I know the Id, and setting the id to final. This way, more errors can be detected at compile time.
I have this class, similar to JDK's AtomicReference, and I use it mostly for legacy code:
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
#NotThreadSafe
public class PermanentReference<T> {
private T reference;
public PermanentReference() {
}
public void set(final #Nonnull T reference) {
checkState(this.reference == null,
"reference cannot be set more than once");
this.reference = checkNotNull(reference);
}
public #Nonnull T get() {
checkState(reference != null, "reference must be set before get");
return reference;
}
}
I has single responsibilty and check both get and set calls, so it fails early when client code misuse it.
Here are two ways; the first is basically the same as some others mentioned in other answers, but it is here to constrast with the seconds. So the first way, Once is to have a value that can be set only once by enforcing that in the setter. My implementation requires non-null values, but if you want to be able to set to null, then you would need to implement an 'isSet' boolean flag as suggested in other answers.
The second way, Lazy, is to provide a function that lazily supplies the value once the first time the getter is called.
import javax.annotation.Nonnull;
public final class Once<T>
{
private T value;
public set(final #Nonnull T value)
{
if(null != this.value) throw new IllegalStateException("Illegal attempt to set a Once value after it's value has already been set.");
if(null == value) throw new IllegalArgumentException("Illegal attempt to pass null value to Once setter.");
this.value = value;
}
public #Nonnull T get()
{
if(null == this.value) throw new IllegalStateException("Illegal attempt to access unitialized Once value.");
return this.value;
}
}
public final class Lazy<T>
{
private Supplier<T> supplier;
private T value;
/**
* Construct a value that will be lazily intialized the
* first time the getter is called.
*
* #param the function that supplies the value or null if the value
* will always be null. If it is not null, it will be called
* at most one time.
*/
public Lazy(final Supplier<T> supplier)
{
this.supplier = supplier;
}
/**
* Get the value. The first time this is called, if the
* supplier is not null, it will be called to supply the
* value.
*
* #returns the value (which may be null)
*/
public T get()
{
if(null != this.supplier)
{
this.value = this.supplier.get();
this.supplier = null; // clear the supplier so it is not called again
// and can be garbage collected.
}
return this.value;
}
}
So you might use these as follows;
//
// using Java 8 syntax, but this is not a hard requirement
//
final Once<Integer> i = Once<>();
i.set(100);
i.get(); // returns 100
// i.set(200) would throw an IllegalStateException
final Lazy<Integer> j = Lazy<>(() -> i);
j.get(); // returns 100
try have an int checker like
private long id = 0;
static int checker = 0;
public void methodThatWillSetValueOfId(stuff){
checker = checker + 1
if (checker==1){
id = 123456;
}
}
//u can try this:
class Star
{
private int i;
private int j;
static boolean a=true;
Star(){i=0;j=0;}
public void setI(int i,int j) {
this.i =i;
this.j =j;
something();
a=false;
}
public void printVal()
{
System.out.println(i+" "+j);
}
public static void something(){
if(!a)throw new ArithmeticException("can't assign value");
}
}
public class aClass
{
public static void main(String[] args) {
System.out.println("");
Star ob = new Star();
ob.setI(5,6);
ob.printVal();
ob.setI(6,7);
ob.printVal();
}
}
Marking a field private and not exposing a setter should be sufficient:
public class Example{
private long id=0;
public Example(long id)
{
this.id=id;
}
public long getId()
{
return this.id;
}
if this is insufficient and you want someone to be able to modify it X times you can do this:
public class Example
{
...
private final int MAX_CHANGES = 1;
private int changes = 0;
public void setId(long id) throws Exception {
validateExample();
changes++;
if ( this.id == 0 ) {
this.id = id;
} else {
throw new Exception("Can't change id once set");
}
}
private validateExample
{
if(MAX_CHANGES==change)
{
throw new IllegalStateException("Can no longer update this id");
}
}
}
This approach is akin to design by contract, wherein you validate the state of the object after a mutator (something that changes the state of the object) is invoked.
I think the singleton pattern might be something you should look into. Google around a bit to check if this pattern meets your design goals.
Below is some sudo code on how to make a singleton in Java using enum. I think this is based off Joshua Bloch's design outlined in Effective Java, either way it's a book worth picking up if you don't have it yet.
public enum JavaObject {
INSTANCE;
public void doSomething(){
System.out.println("Hello World!");
}
}
Usage:
JavaObject.INSTANCE.doSomething();
I'm trying to mimic the following abstract class, designed to enable only one lazy initialization, without using logic statements. I'm ignoring the synchronization elements necessary for thread safety for simplicity's sake.
abstract class Thunk<T>
{
private boolean initiated = false;
private T value;
public T get()
{
if(!initiated) // not using (value == null)
{
value = compute();
initiated = true;
}
return value;
}
abstract protected T compute();
}
Can an instance of the following abstract class be hacked by a child to initialize the same variable more than once?
abstract class Thunk<T>
{
private T value;
private Computer<T> computer;
public Thunk()
{
computer = new Computer<T>(this);
}
public T get()
{
value = computer.getValue();
return value;
}
abstract protected T compute();
private class Computer<T>
{
private static final String TAG = "Computer";
private Thunk<T> thunk;
private T value;
private Computer<T> computer;
public Computer(Thunk<T> thunk)
{
Log.d(TAG, "constructed");
this.thunk = thunk;
computer = this;
}
public T getValue()
{
Log.d(TAG + ".getValue()", "");
value = computer.computeValue();
return value;
}
protected T computeValue()
{
Log.d(TAG + ".computeValue()", "");
value = thunk.compute();
computer = new DumbComputer<T>(thunk, value);
return value;
}
//this is for maximal encapsulation
private class DumbComputer<T> extends Computer<T>
{
private static final String TAG = "DumbComputer";
private T value;
public DumbComputer(Thunk<T> thunk, T value)
{
super(thunk);
Log.d(TAG + ".contructed()", "booki");
this.value = value;
}
//overriding so that value will be calculated only once.
#Override
protected T computeValue()
{
Log.d(TAG + ".computeValue()", "");
return value;
}
}
}
}
Yes, by overriding the get method.
To fix that you can make the get into a final method. That will prevent overriding and give you singleton-like behaviour.
Note that the code you have written is not thread safe.
You could achieve thread safety by making the method synchronized (don't worry about performance until you know you gave a problem and that the method is the hotspot, because slow correct code is better than fast incorrect code, and the JVM is very good at optimising locks. If you find a specific lock for this class to be excessively hot, you can use a number of tricks to speed it up... but don't worry about that just yet)
Also worth pointing out the resource holder inner class pattern for lazy init (not applicable to your use case as this class need. It be used for only singletons) can be used if you wan the best lazy init of singletons.
update (responding to comment as comments don't support formatting)
Do this:
abstract class Thunk<T>
{
private boolean initiated = false;
private T value;
public synchronized final T get()
{
if(!initiated) // not using (value == null)
{
value = compute();
initiated = true;
}
return value;
}
abstract protected T compute();
}
That is the simplest code that can possibly work. Don't even dream of trying to "improve" that code. It can be improved, but the improvements will differ depending on how the class is being used, and the complexity of the improvement will hide what your code is trying to do. Start with the simplest thing that can work, and go from there.
Keep It Simple Stupid
And don't solve problems you don't have yet
The pattern
public final void f() {
...
X x = ...;
g(x);
...
}
abstract protected void g(X x);
is quite usefull in contractual programming:
to impose a behaviour (body of f), and
to provide a local context (x).
A behaviour often is realized by holding a state (like your initiated).
So yes, it is fine for lazy evaluation. Though lazy evaluation can be achieved on field level, for instance by the seldom seen jewel Future<>.
Your second example does not work as (probably) intended, as you create a new DumbComputer each time you call Thunk.get. You can achieve your goal as follows (but I do not think it's good design, and I really do not see where the advantage compared to an easier solution shuld be):
abstract class Thunk<T> {
T value;
Computer<T> computer;
protected abstract T doCompute ();
private interface Computer<T> {
Computer getComputer ();
T compute ();
}
public Thunk<T> () {
// initialize computer with a calculating one
computer = new Computer<T> () {
Computer getComputer () {
// return a dumb computer
return new Computer<T> () {
Computer getComputer () { return this; }
T compute () { return value; }
}
}
T compute () { value = doCompute (); return value; }
};
}
public T getValue () {
T v = computer.compute (); computer = computer.getComputer (); return v;
}
}
I am currently working with XML files, and am searching to have a better way to avoid try/catch blocks in a nice way.
Here is the thing. Let's say I have an XML file.
<A>
<BB>37</BB>
<CC>
<DDD>1</DDD>
</CC>
</A>
In fact, I turn this into an object, which means that I can do
myXml.getA() and so on.
In my code, I search a lot for given elements in this object, which means that I have a lot of lines like
int ddd = myXml.getA().getCC().getDDD();
The thing is that some elements may not be there, and for example another XML element can be like that only :
<A'>
<BB'>37</BB'>
</A'>
So if I try to get ddd, getCC() raises a NullPointerException.
In the end, I end up coding it like that :
int ddd;
try{
ddd = myXml.getA().getCC().getDDD();
}
catch (NullPointerException e){
ddd = 0;
}
This works but the code becomes really ugly.
I am searching for a solution to have something like
int ddd = setInt(myXml.getA().getCC().getDDD(), 0);
0 being the default in case the method raises an exception.
Is there a nice way to do that ?
Up to now, I couldn't find a solution that do not raise errors.
Thx for your help !
EDIT: Just not to get XML related answers.
I showed the xml part for everybody to understand the problem.
In my code, I don't have access to the XML, but only the object that represents it.
To make it short, what I'd really love is some kind of isNull method to test my getters.
This is sort of an annoyance of working with jaxb. in my company, we do enough work with jaxb that it was worth writing an xjc plugin which generated "safe" versions of every getter that were guaranteed to return non-null values for any non-trivial value (immutable instances in the case that a sub-object did not really exist).
Here's an example of what our generated model entities look like:
public class ExampleUser implements Serializable {
private final static long serialVersionUID = 20090127L;
#XmlAttribute
protected String name;
#XmlAttribute
protected String email;
public final static ExampleUser EMPTY_INSTANCE = new ExampleUser() {
private static final long serialVersionUID = 0L;
#Override
public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
#Override
public void setEmail(java.lang.String value) { throw new UnsupportedOperationException(); }
};
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getEmail() {
return email;
}
public void setEmail(String value) {
this.email = value;
}
}
public class ExampleAccount implements Serializable {
private final static long serialVersionUID = 20090127L;
protected ExampleUser user;
#XmlElement(name = "alias")
protected List<String> aliases;
#XmlAttribute
protected String id;
#XmlAttribute
protected String name;
public final static ExampleAccount EMPTY_INSTANCE = new ExampleAccount() {
private static final long serialVersionUID = 0L;
#Override
public void setUser(com.boomi.platform.api.ExampleUser value) { throw new UnsupportedOperationException(); }
#Override
public List<String> getAliases() { return java.util.Collections.emptyList(); }
#Override
public void setId(java.lang.String value) { throw new UnsupportedOperationException(); }
#Override
public void setName(java.lang.String value) { throw new UnsupportedOperationException(); }
};
public ExampleUser getUser() {
return user;
}
public void setUser(ExampleUser value) {
this.user = value;
}
public List<String> getAliases() {
if (aliases == null) {
aliases = new ArrayList<String>();
}
return this.aliases;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public ExampleUser safeGetUser() {
return (getUser() != null) ? getUser() : ExampleUser.EMPTY_INSTANCE;
}
}
So you could write this code without fear of NPE:
userEmail = account.safeGetUser().getEmail();
You can look at the Null objec pattern.
For example :
public class A {
private C c;
public C getC() {
if (c == null) {
c = new C(0); // the "null object"
}
return c;
}
}
public class C {
private int d;
public C(int d) {
this.d = d;
}
public int getD() {
return d;
}
}
But personnaly, i have a bad feeling with this code :
int ddd = myXml.getA().getCC().getDDD();
It is a strong violation of the law of Demeter. The class invoker have a too large knowledge of A, C and D. This code will be clearly difficult to adapt and maintain.
The two general approaches to this sort of problem are the null object pattern that other answers have already covered, and type safe nulls such as Scala's Option.
http://www.scala-lang.org/api/current/scala/Option.html
There are a few Java versions of Option knocking around.
http://functionaljava.googlecode.com/svn/artifacts/2.20/javadoc/fj/data/Option.html
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html
Type safe nulls can be particular useful when combined with the flatmap.
Use Apache common-beanutils to create your set method. It will use reflection and then you have only a single place to catch the errors.
It would look something like this (haven't coded it so excuse syntax errors).
int getInt(Object root, String beanPattern, int defaultValue)
{
try
{
return PropertyUtils.getNestedProperty(root, beanPattern);
}
catch (Exception e)
{
return 0;
}
}
This would be called like so.
int ddd = getInt(myXml, "A.CC.DDD", 0);
Can't you just write a function which is general enough to be called for each value, and is returning the value or 0.
Something like
myGetSomething(FOO){
try {getFOO} catch ...
}
Then your Code itself looks nice, but the function has basically a try-catch for each call.
Use Xpath query instead of get methods. It will give you an empty list if it cannot find the element path.
List ddds = myXml.query("/AA/BB/CC/DDD");
if (!ddds.empty()) {}
The correct syntax depends on the XML library you use.
Write part of the code in Groovy or Xtend; both support the ?. syntax which returns null of the left hand side of the expression evaluates to null. They also get rid of the useless get so you can write:
myXml.a?.cc?.ddd
The syntax of Xtend is worse when compared to Groovy but it compiles to plain Java, so you just need to add a single JAR with some helper classes to your code to use the result.