equality and null pointers

Discussion in 'Java' started by julien.robinson2@gmail.com, Apr 11, 2007.

  1. Guest

    Hi all, a code factorization question...

    the following expression:
    a.equals(b)
    returns a boolean, even if 'b' is null (in which case it's obviously
    false, because otherwise there would be a NullPointerException).

    This is great for tests such as:
    "blob".equals(myPersonalString)

    What if both a and b can be null? I end up writing the same code again
    and again... calling for factorization.

    This is the factorized code:

    public class Utils {
    public static boolean areEqual(Object obj1, Object obj2) {
    return (obj1 == null) ? (obj2 == null) : (obj1.equals(obj2));
    }
    }

    Questions are:
    - does this already exist somewhere in Java, and I have overlooked it
    (buried somewhere in with other utility methods)?
    - if not, does anybody prefer some other code than what I suggested?

    This is nothing important, it's just annoying. I hate to rewrite code,
    and I don't like to define utilities that already exist, and it's such
    an insignificant problem... :)

    Thanks to all
    JR
    , Apr 11, 2007
    #1
    1. Advertising

  2. visionset Guest

    <> wrote in message
    news:...
    >
    > Hi all, a code factorization question...
    >
    > the following expression:
    > a.equals(b)
    > returns a boolean, even if 'b' is null (in which case it's obviously
    > false, because otherwise there would be a NullPointerException).


    Well here lies your problem.
    Personally I'd say it was more likely that
    null != null
    Just like in SQL.

    So this underlines the fact that only you, your design in your application
    can determine what equality is.
    For the same reason you override equals() to put your spin on equality so
    you must determine if null == null, nul!=null or indeed what
    myObj.equals(null) should evaluate to.

    >
    > This is great for tests such as:
    > "blob".equals(myPersonalString)
    >
    > What if both a and b can be null? I end up writing the same code again
    > and again... calling for factorization.
    >
    > This is the factorized code:
    >
    > public class Utils {
    > public static boolean areEqual(Object obj1, Object obj2) {
    > return (obj1 == null) ? (obj2 == null) : (obj1.equals(obj2));
    > }
    > }
    >
    > Questions are:
    > - does this already exist somewhere in Java, and I have overlooked it
    > (buried somewhere in with other utility methods)?
    > - if not, does anybody prefer some other code than what I suggested?
    >



    --
    Mike W
    visionset, Apr 11, 2007
    #2
    1. Advertising

  3. Guest

    On Apr 11, 11:45 am, "visionset" <> wrote:
    > <> wrote in message
    >
    > news:...
    >
    >
    >
    > > Hi all, a code factorization question...

    >
    > > the following expression:
    > > a.equals(b)
    > > returns a boolean, even if 'b' is null (in which case it's obviously
    > > false, because otherwise there would be a NullPointerException).

    >
    > Well here lies your problem.
    > Personally I'd say it was more likely that
    > null != null
    > Just like in SQL.
    >
    > So this underlines the fact that only you, your design in your application
    > can determine what equality is.
    > For the same reason you override equals() to put your spin on equality so
    > you must determine if null == null, nul!=null or indeed what
    > myObj.equals(null) should evaluate to.
    >
    >
    >
    >
    >
    >
    >
    > > This is great for tests such as:
    > > "blob".equals(myPersonalString)

    >
    > > What if both a and b can be null? I end up writing the same code again
    > > and again... calling for factorization.

    >
    > > This is the factorized code:

    >
    > > public class Utils {
    > > public static boolean areEqual(Object obj1, Object obj2) {
    > > return (obj1 == null) ? (obj2 == null) : (obj1.equals(obj2));
    > > }
    > > }

    >
    > > Questions are:
    > > - does this already exist somewhere in Java, and I have overlooked it
    > > (buried somewhere in with other utility methods)?
    > > - if not, does anybody prefer some other code than what I suggested?

    >
    > --
    > Mike W- Hide quoted text -
    >
    > - Show quoted text -


    Here is some code showing equals and hascode that you can implement in
    your calsses.


    public class Worker {
    private String name;
    private double salaryRate;


    public Worker (String name, double rate) {
    this.name = name;
    this.salaryRate = rate;
    }

    public int hashCode() {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + ((name == null) ? 0 :
    name.hashCode());
    long temp;
    temp = Double.doubleToLongBits(salaryRate);
    result = PRIME * result + (int) (temp ^ (temp >>> 32));
    return result;
    }

    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    final Worker other = (Worker) obj;
    if (name == null) {
    if (other.name != null)
    return false;
    } else if (!name.equals(other.name))
    return false;
    if (Double.doubleToLongBits(salaryRate) !=
    Double.doubleToLongBits(other.salaryRate))
    return false;
    return true;
    }
    }

    Dinesh
    , Apr 11, 2007
    #3
  4. Lew Guest

    visionset wrote:
    > Well here lies your problem.
    > Personally I'd say it was more likely that
    > null != null
    > Just like in SQL.



    There is no "likely" in Java. There is what it is, and there isn't what it
    ain't. One thing it ain't is probabilistic.

    Why in the world should anything in Java be "just like in SQL"? Java is
    nothing like SQL.

    (null == null) is true, just for your reference.

    > So this underlines the fact that only you, your design in your application
    > can determine what equality is.
    > For the same reason you override equals() to put your spin on equality so
    > you must determine if null == null, nul!=null or indeed what
    > myObj.equals(null) should evaluate to.


    Come on, already! I'm sorry, but I have absolutely no idea where you came up
    with this. I am very interested in how people learn Java. From where did you
    learn this poppycock?

    == is precisely defined and set by the rules of the Java language. What are
    you, Humpty Dumpty?

    > 'When _I_ use a word,' Humpty Dumpty said in rather a scornful tone,
    > 'it means just what I choose it to mean--neither more nor less.'

    - /Through the Looking Glass/, Lewis Carroll

    It is totally not up to the OP, you or me what == means. And there is no
    mechanism in Java to "put your spin on" it, either.

    To the OP:

    You should be range-checking values anyway. It is not redundant to check for
    both null and the empty string; they are different values.

    It's not so bad to write a utility method like the one you showed if you
    commonly treat both null and "" as equivalently undesirable. However, the
    language itself treats the cases differently because they are.

    --
    Lew
    Lew, Apr 12, 2007
    #4
  5. visionset Guest

    "Lew" <> wrote in message
    news:...

    >> Well here lies your problem.
    >> Personally I'd say it was more likely that
    >> null != null
    >> Just like in SQL.

    >
    >
    > There is no "likely" in Java. There is what it is, and there isn't what
    > it ain't. One thing it ain't is probabilistic.
    >
    > Why in the world should anything in Java be "just like in SQL"? Java is
    > nothing like SQL.
    >
    > (null == null) is true, just for your reference.


    No shit sherlock.

    >
    >> So this underlines the fact that only you, your design in your
    >> application can determine what equality is.
    >> For the same reason you override equals() to put your spin on equality so
    >> you must determine if null == null, nul!=null or indeed what
    >> myObj.equals(null) should evaluate to.

    >
    > Come on, already! I'm sorry, but I have absolutely no idea where you came
    > up with this. I am very interested in how people learn Java. From where
    > did you learn this poppycock?
    >
    > == is precisely defined and set by the rules of the Java language. What
    > are you, Humpty Dumpty?
    >
    >> 'When _I_ use a word,' Humpty Dumpty said in rather a scornful tone,
    >> 'it means just what I choose it to mean--neither more nor less.'

    > - /Through the Looking Glass/, Lewis Carroll
    >
    > It is totally not up to the OP, you or me what == means. And there is no
    > mechanism in Java to "put your spin on" it, either.
    >


    I'd have thought it was quite obvious that I'm talking about the Java
    languages definitions.
    That is so simple, I'd not even reply with that information.
    I'm obviously talking about what null means and how it relates to other
    values **for your business logic**
    Pehaps I shouldn't have used the same syntax. But like I said I thought it
    was obvious.
    It obviously was to most, otherwise I wouldn't escaped such abuse for so
    long...

    > To the OP:
    >
    > You should be range-checking values anyway. It is not redundant to check
    > for both null and the empty string; they are different values.
    >
    > It's not so bad to write a utility method like the one you showed if you
    > commonly treat both null and "" as equivalently undesirable.


    'if you treat'
    ie
    your applications business logic is such that...

    > However, the language itself treats the cases differently because they
    > are.
    >


    --
    Mike W
    visionset, Apr 12, 2007
    #5
  6. Guest

    in fact, you provide an example of use of what I was talking about...

    On Apr 11, 6:37 pm, wrote:
    > Here is some code showing equals and hascode that you can implement in
    > your calsses.

    [snip]
    > if (name == null) {
    > if (other.name != null)
    > return false;
    > } else if (!name.equals(other.name))
    > return false;


    This piece of code is more or less equivalent to calling my
    "areEqual(name, other.name)" (except that I prefer my version, sorry).

    So basically, you're answering my need for factorization with "don't
    factorize, write it". :)

    Thanks all the same
    JR
    , Apr 12, 2007
    #6
  7. Lew Guest

    visionset wrote:
    > I'd have thought it was quite obvious that I'm talking about the Java
    > languages definitions.
    > That is so simple, I'd not even reply with that information.
    > I'm obviously talking about what null means and how it relates to other
    > values **for your business logic**
    > Pehaps I shouldn't have used the same syntax. But like I said I thought it
    > was obvious.


    I am sorry that I misunderstood what you were saying. Could you explain it?

    When you say it's up to the programmer
    >> For the same reason you override equals() to put your spin on equality so
    >>> you must determine if null == null, nul!=null


    How can you decide that null != null? The language says that null == null.

    --
    Lew
    Lew, Apr 12, 2007
    #7
  8. visionset Guest

    "Lew" <> wrote in message
    news:...
    > visionset wrote:
    >> I'd have thought it was quite obvious that I'm talking about the Java
    >> languages definitions.
    >> That is so simple, I'd not even reply with that information.
    >> I'm obviously talking about what null means and how it relates to other
    >> values **for your business logic**
    >> Pehaps I shouldn't have used the same syntax. But like I said I thought
    >> it was obvious.

    >
    > I am sorry that I misunderstood what you were saying. Could you explain
    > it?
    >
    > When you say it's up to the programmer
    >>> For the same reason you override equals() to put your spin on equality
    >>> so
    >>>> you must determine if null == null, nul!=null

    >
    > How can you decide that null != null? The language says that null ==
    > null.
    >


    Like I said for the purposes of your problem space.
    I did not actually mean:

    if (null != null) System.out.println("look, I've just proved the JLS
    wrong");

    I meant that if two of your domain objects of type Foo are null then they
    are probably not 'equal' where equality is something defined by your domain
    logic. But then they could be, this is where 'you decide' means
    applicability to you domain.

    Boy do I regret lazily using syntax that could be confused with Java source.
    But then it's shared by the majority of languages these days.

    --
    Mike W
    visionset, Apr 12, 2007
    #8
  9. Guest

    On Apr 12, 3:26 am, Lew <> wrote:
    > There is no "likely" in Java. There is what it is, and there isn't what it
    > ain't. One thing it ain't is probabilistic.


    Thanks. :)

    [To visionset:]
    >From what I understand, you're in fact saying, *not* that (null !=

    null), but that it's probably not a good idea to use that test in
    code, because null is a special value and should be treated as such.
    Is that what you're saying?
    I see your point, even if I don't think it's a generalizable good
    practice rule. For me, null values should generally be documented, and
    that's where my personal rules stop. They may be meaningful, and their
    comparison too, in many cases.

    [back to Lew]
    > To the OP:


    Hi! :)

    > You should be range-checking values anyway. It is not redundant to check for
    > both null and the empty string; they are different values.


    If I may say so, you are answering a special case of my question. The
    string stuff was an example. In fact, you're more or less saying the
    same as visionset: treat the null values as special values, don't
    compare them! I agree in some cases (I'm not speaking of those here),
    not in all cases.

    > It's not so bad to write a utility method like the one you showed if you
    > commonly treat both null and "" as equivalently undesirable. However, the
    > language itself treats the cases differently because they are.


    I'm not blaming the language! Of course it treats them differently...
    in fact, it doesn't treat null at all in this case, because
    "null.equals(null)" simply throws a null pointer exception (as well it
    should). :)

    Here's an example of what I'm saying:

    public class MyStuff {
    private A a;
    private B b;
    /* ...many others... */

    @Override
    public boolean equals(Object obj) {
    if (obj == null) {
    return false;
    }
    if (obj == this) {
    return true;
    }
    if (! (obj instanceof EntityAction)) {
    return false;
    }
    MyStuff otherStuff = (MyStuff) obj;
    return Utils.areEqual(a, otherStuff.a)
    & Utils.areEqual(b, otherStuff.b); // ..and all the other
    stuff
    }
    }

    If I wasn't using my utility method, I would simply be copy-pasting
    code all around (which is what <> suggested). And
    of course, sometimes null values are special, but in the "equals()"
    method, I simply want to compare two instances. Let's say it's for the
    sake of a collections utility method, searching, sorting etc. I don't
    want any checking logic in there, because if there is any null value
    management, it should be in the constructor, the setter, the
    deserializer or someplace like that. It's not up to the "equals()"
    method to refuse / accept null values.
    If I may add, if business logic implies that "a" cannot be null, the
    code could simply be...

    return a.equals(otherStuff.a)
    & Utils.areEqual(b, otherStuff.b); // ..and all the other
    stuff

    I still think I need this method. I'm sure many people need it, and
    among those who don't, a lot surely simply forget a couple of
    defensive tests or don't mind about code copying (I've come across
    both)... which is not *extremely* bad, as I said before it's a minor
    point, I've seen worse. :)
    My questions, open as they were, were more about how to best do it and
    does it exist... Apparently it doesn't exist in Java utilities. Too
    bad. This being said, thanks for the answers!
    JR
    , Apr 12, 2007
    #9
  10. Chris Uppal Guest

    wrote:

    > public class Utils {
    > public static boolean areEqual(Object obj1, Object obj2) {
    > return (obj1 == null) ? (obj2 == null) : (obj1.equals(obj2));
    > }
    > }


    Just as a side comment. It's pretty unusual to use null as an explicit
    value -- say (just for the sake of argument) that 1 in 100 methods allow null
    parameters of some sort. So the number of methods which will expect/allow null
    in /two/ parameters will be correspondingly smaller (1 in 10000 in this
    example). I doubt whether it is worth creating utility methods to help with
    cases that crop up so rarely.

    Put it another way: if you are passing around so many nulls, then you may be
    overusing nulls-as-values in your designs.

    -- chris
    Chris Uppal, Apr 12, 2007
    #10
  11. Wojtek Guest

    visionset wrote :
    >
    > I meant that if two of your domain objects of type Foo are null then they are
    > probably not 'equal' where equality is something defined by your domain
    > logic. But then they could be, this is where 'you decide' means applicability
    > to you domain.


    An object will never be null. It either exists or it does not.

    A reference, on the other hand, can refer to an object (not null) or
    can refer to null (is null).

    --
    Wojtek :)
    Wojtek, Apr 12, 2007
    #11
  12. visionset Guest

    "Wojtek" <> wrote in message
    news:...
    > visionset wrote :
    >>
    >> I meant that if two of your domain objects of type Foo are null then they
    >> are probably not 'equal' where equality is something defined by your
    >> domain logic. But then they could be, this is where 'you decide' means
    >> applicability to you domain.

    >
    > An object will never be null. It either exists or it does not.
    >
    > A reference, on the other hand, can refer to an object (not null) or can
    > refer to null (is null).
    >


    Yes sloppy terminology, I do appologise!
    --
    Mike W
    visionset, Apr 12, 2007
    #12
  13. Stefan Ram Guest

    Wojtek <> writes:
    >An object will never be null. It either exists or it does not.

    ¯¯¯¯¯¯¯¯
    An object that does not exist is not an object at all.
    Therefore, an object always exists.

    (The phrase »not exists« actually makes sense in the
    context of object descriptions P: When there is no
    object so that P(o) is true, one says informally
    »io:p(o) does not exist.«, i.e., »The object o, so
    that P(o), does not exists.«. This does not mean,
    however, that there are objects that do not exists.
    Those objects would exist and not exist.)
    Stefan Ram, Apr 12, 2007
    #13
  14. Wojtek Guest

    Stefan Ram wrote :
    > Wojtek <> writes:
    >> An object will never be null. It either exists or it does not.

    > ¯¯¯¯¯¯¯¯
    > An object that does not exist is not an object at all.
    > Therefore, an object always exists.
    >
    > (The phrase »not exists« actually makes sense in the
    > context of object descriptions P: When there is no
    > object so that P(o) is true, one says informally
    > »io:p(o) does not exist.«, i.e., »The object o, so
    > that P(o), does not exists.«. This does not mean,
    > however, that there are objects that do not exists.
    > Those objects would exist and not exist.)


    Between my phrase "It either exists or it does not" and your phrase
    "Those objects would exist and not exist" there is not a lot of
    difference.....

    My point was that it is not an object which is null, but rather a
    reference which can refer to a null.

    --
    Wojtek :)
    Wojtek, Apr 12, 2007
    #14
  15. visionset Guest

    "Wojtek" <> wrote in message
    news:...

    >> however, that there are objects that do not exists.
    >> Those objects would exist and not exist.)

    >
    > Between my phrase "It either exists or it does not" and your phrase "Those
    > objects would exist and not exist" there is not a lot of difference.....
    >
    > My point was that it is not an object which is null, but rather a
    > reference which can refer to a null.
    >


    He was upping the pedantry to def con one, one more than you ;-/

    --
    Mike W
    visionset, Apr 12, 2007
    #15
  16. "visionset" <> wrote in message
    news:6EpTh.1145$%...
    > I meant that if two of your domain objects of type Foo are null then they
    > are probably not 'equal' where equality is something defined by your
    > domain logic. But then they could be, this is where 'you decide' means
    > applicability to you domain.


    And at the primitive level, you may sometimes want NaN to be
    equal to NaN, although they will compare as not equal. For example,
    double x = Math.sqrt(-2);
    System.out.println((x == x));
    prints "false".
    Larry Barowski, Apr 12, 2007
    #16
  17. Guest

    On Apr 12, 2:54 pm, "Chris Uppal" <-
    THIS.org> wrote:
    > Put it another way: if you are passing around so many nulls, then you may be
    > overusing nulls-as-values in your designs.


    This got me thinking about frequency, not methods. So I quizzed my
    source. I've just written the utility, so I didn't know yet how many
    times it would prove useful in my current project.

    These are the statistics (please restrain from laughing out loud :) )
    .. 262 classes
    .. 3 classes where it's useful.

    2 of these are the equals() method.
    The other is a collection manipulation (so it's more or less
    equals()).

    All around, in fact, null values are specifically managed, and often
    forbidden from the start. Ergo, the code already follows the advice of
    you all (well, 259 times out of 262!). :)

    Which could mean that in this discussion everyone was right. :)
    * Yes, beware of null pointers and manage them separately.
    * But yes, it's sometimes useful to use my code (and since no one has
    suggested better, I'll keep it as a static utility method in a
    separate class).

    So there you go. Still, I was happy to see what other coders thought
    about this...
    JR
    , Apr 12, 2007
    #17
  18. Lew Guest

    Larry Barowski wrote:
    > And at the primitive level, you may sometimes want NaN to be
    > equal to NaN, although they will compare as not equal. For example,
    > double x = Math.sqrt(-2);
    > System.out.println((x == x));
    > prints "false".


    Why would one want NaN to equal NaN? Doesn't that violate the fundamental
    meaning of NaN?

    --
    Lew
    Lew, Apr 13, 2007
    #18
  19. Lew <> writes:

    > Why would one want NaN to equal NaN? Doesn't that violate the
    > fundamental meaning of NaN?


    Apparently, at least when you want to use Doubles as hash table keys.
    See
    <http://java.sun.com/javase/6/docs/api/java/lang/Double.html#equals(java.lang.Object)>.

    It also makes sense when you're, say, writing data marshaling and
    unmarshaling code and need to test it.

    --
    Jaakko Kangasharju, Helsinki Institute for Information Technology
    Want a Gmail account? Just email me.
    Jaakko Kangasharju, Apr 13, 2007
    #19
  20. Chris Uppal Guest

    wrote:

    > These are the statistics (please restrain from laughing out loud :) )
    > . 262 classes
    > . 3 classes where it's useful.


    Thanks for the follow-up. It's always interesting to see real numbers in
    questions like this.

    -- chris
    Chris Uppal, Apr 13, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jbj
    Replies:
    9
    Views:
    397
    Roedy Green
    Jul 16, 2004
  2. Replies:
    5
    Views:
    26,502
    Mike Schilling
    Mar 29, 2006
  3. Roger Leigh
    Replies:
    8
    Views:
    420
    Karl Heinz Buchegger
    Nov 17, 2003
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    656
  5. V.Subramanian, India

    Can function pointers be compared for equality

    V.Subramanian, India, Jan 23, 2012, in forum: C Programming
    Replies:
    22
    Views:
    1,177
    ec429
    Jan 24, 2012
Loading...

Share This Page