开发者

How to achieve differentiation between undef and null values for java data types

What is the common approach followed in applications if we have to differentiate between 'undefined' value and 'null' value for properties in a class?

For example, let's say we have a class A

public class A {
 Integer int1;
 Boolean bool1;
 Double doub1;
 String str1;
}

In the co开发者_如何学Pythonde, we would like to differentiate if each property of A is either set or not set (null is a VALID value to set).

One approach is to have custom data types extending from java datatypes. Other approach is to assign some arbitrarily unreachable values to each of the data types and treat those values as undef.

Are there any other better approaches?


I would use generics to create a wrapper which includes a 'set' flag.

public class Settable<T> {

  private boolean isSet = false;
  private T value;

  public Settable() {}

  public boolean isSet() {return isSet;}
  public T value() { return value;}
  public void set(T t) { value = t; isSet = true;}
}

...then declare your class with e.g.

public class A {
  //...
  Settable<Integer> int1;
  //...
}


What should be returned, if you call a getter on an undefined value? Should a fallback be returned? Or null?

Depending on that you can manage the undefined values in the holder class itself (BitSet comes to mind), and provide isXXXSet() functions, or you use sje397's Settable.


As an alternative to sje397's answer, you could write a simple concrete class that acts like a Reference. Set the reference field itself to null to indicate unset or undefined.

public class Ref<T> {
    private T value;

    /**
     * Sets the reference
     * @param value the new value
     */
    public void set(T value) {
        this.value = value;
    }

    /**
     * Get the referenced value
     * @return the value
     */
    public T get() {
        return this.value
    }

    /**
     * Syntatic sugar factory
     * @return a Ref<T>
     */
    public static Ref<T> to(T value) {
        Ref<T> ref = new Ref<T>();
        ref.set(value);
        return ref;
    }
}

Used like:

public class A {

    Ref<Integer> int1;
    Ref<Boolean> bool1;
    // etc.
}

int1 will initially be null or unset. To set it, just go:

a.int1 = Ref.to(someInt);

To set a null value:

if (a.int1 != null) {
   a.int1.set(null);
} else {
   a.int1 = Ref.to(null);
}

To unset, then just set the reference itself to null.

The main difference of this approach is one less variable to track the set/unset state. However, this necessitates null-checking of the field itself, as demonstrated above.

I would personally choose this approach if the values are relatively immutable after being set. That is, they're either unset or set to an unchanging value (which could be null), and in that case, I would remove the set() method altogether.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜