Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

equality and null pointers

Thread view: 
julien.robinson2@gmail.com - 11 Apr 2007 16:13 GMT
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
visionset - 11 Apr 2007 16:45 GMT
> 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)
[quoted text clipped - 14 lines]
> (buried somewhere in with other utility methods)?
> - if not, does anybody prefer some other code than what I suggested?

Signature

Mike W

CodeForTea@gmail.com - 11 Apr 2007 17:37 GMT
> <julien.robins...@gmail.com> wrote in message
>
[quoted text clipped - 41 lines]
>
> - 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
julien.robinson2@gmail.com - 12 Apr 2007 13:05 GMT
in fact, you provide an example of use of what I was talking about...

On Apr 11, 6:37 pm, CodeFor...@gmail.com 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
CodeForTea@gmail.com - 13 Apr 2007 12:22 GMT
On Apr 12, 8:05 am, julien.robins...@gmail.com wrote:
> in fact, you provide an example of use of what I was talking about...
>
[quoted text clipped - 17 lines]
> Thanks all the same
> JR

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

}
I fail to see how this helps.  Why do you need two methods to compare
an object when one will do? You call the equals method in your
areEqual method.

Dinesh
julien.robinson2@gmail.com - 16 Apr 2007 08:19 GMT
On Apr 13, 1:22 pm, CodeFor...@gmail.com wrote:
> I fail to see how this helps.  Why do you need two methods to compare
> an object when one will do? You call the equals method in your
> areEqual method.
>
> Dinesh

Hi, I feel like we're talking at right angles here. :-)

Let me try to explain...
I was asking about code factorization. It's a piece of code that I
write very often*, and it's (very) good practice in that case to
factorize, i.e. write it only once and then call it.

You answered me with some equals() code.
1. the "equals" method itself does not address my problem, because I
was speaking about 2 pointers that may both be null... and you can't
call "equals" on a null pointer
2. inside your "equals" method was a part (that I quoted) that looked
like what I was doing, so I assumed that was what you were talking
about, and answered that.

Hope this clears it up. If not, it's just a slight miscomprehension,
no great deal. :-)

The answer to your last question is:
. I use the "equals" method, only one method, when I'm sure I have a
non-null pointer to call it on
. the other method is for pointers that I'm not sure are null or not
. I call "areEqual" in "equals" because that's factorization (avoiding
to write the same code again and again).

JR
* this was before recounting the votes of course :-)
Lew - 12 Apr 2007 02:26 GMT
> 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.

Signature

Lew

visionset - 12 Apr 2007 09:43 GMT
>> Well here lies your problem.
>> Personally I'd say it was more likely that
[quoted text clipped - 8 lines]
>
> (null == null) is true, just for your reference.

No sh.t sherlock.

>> So this underlines the fact that only you, your design in your
>> application can determine what equality is.
[quoted text clipped - 15 lines]
> 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:
>
[quoted text clipped - 3 lines]
> 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.

Signature

Mike W

Lew - 12 Apr 2007 13:07 GMT
> I'd have thought it was quite obvious that I'm talking about the Java
> languages definitions.
[quoted text clipped - 3 lines]
> 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.

Signature

Lew

visionset - 12 Apr 2007 13:30 GMT
>> I'd have thought it was quite obvious that I'm talking about the Java
>> languages definitions.
[quoted text clipped - 14 lines]
> 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.

Signature

Mike W

Wojtek - 12 Apr 2007 15:12 GMT
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).

Signature

Wojtek :-)

visionset - 12 Apr 2007 15:15 GMT
> visionset wrote :
>>
[quoted text clipped - 7 lines]
> 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!
Signature

Mike W

Stefan Ram - 12 Apr 2007 15:18 GMT
>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.)
Wojtek - 12 Apr 2007 15:33 GMT
Stefan Ram wrote :
>> An object will never be null. It either exists or it does not.
>                                                       ¯¯¯¯¯¯¯¯
[quoted text clipped - 8 lines]
>   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.

Signature

Wojtek :-)

visionset - 12 Apr 2007 15:36 GMT
>>   however, that there are objects that do not exists.
>>   Those objects would exist and not exist.)
[quoted text clipped - 4 lines]
> 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 ;-/

Signature

Mike W

Larry Barowski - 12 Apr 2007 16:03 GMT
> 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".
Lew - 13 Apr 2007 02:41 GMT
> 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?

Signature

Lew

Jaakko Kangasharju - 13 Apr 2007 07:26 GMT
> 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.

Signature

Jaakko Kangasharju, Helsinki Institute for Information Technology
Want a Gmail account?  Just email me.

Larry Barowski - 13 Apr 2007 15:22 GMT
>> And at the primitive level, you may sometimes want NaN to be
>> equal to NaN, although they will compare as not equal. For example,
[quoted text clipped - 4 lines]
> Why would one want NaN to equal NaN?  Doesn't that violate the fundamental
> meaning of NaN?

The last time I ran into it was indirectly. I was developing a
Java debugger that highlights fields when their values
change. Naively using com.sun.jdi.DoubleValue.equals()
for comparison of old and new values resulted in float
and double NaN values that were always highlighted after
their first appearance.

Also, in addition to what Jaakko pointed out, you may want
them to be considered equal for sorting purposes (where
you also need to use a different < or > comparison to
compare NaN to non-NaN).

In any case where floating point numbers can be NaN,
you need to watch out for:

if(x > y)
  ...
else if(x < y)
  ...
else
  // Wrongly assume x == y in all cases here.
Lew - 13 Apr 2007 16:51 GMT
> The last time I ran into it was indirectly. I was developing a
> Java debugger that highlights fields when their values
> change. Naively using com.sun.jdi.DoubleValue.equals()
> for comparison of old and new values resulted in float
> and double NaN values that were always highlighted after
> their first appearance.

As you say, "naively" using.  The fault, dear Caesar, lies not in our NaNs,
but in ourselves.

> Also, in addition to what Jaakko pointed out, you may want
> them to be considered equal for sorting purposes

You may want them to be, but they aren't.

> (where you also need to use a different < or > comparison to
> compare NaN to non-NaN).

> In any case where floating point numbers can be NaN,
> you need to watch out for:
[quoted text clipped - 5 lines]
> else
>    // Wrongly assume x == y in all cases here.

That error is the programmer's.  The programmer should not wrongly assume x ==
y in all cases, as you point out.

The very definition of NaN is that it is not comparable to any number, and
that it is not equal to any number.

> a numeric comparison operation involving one or two NaNs returns false and any != comparison involving NaN returns true, including x!=x when x is NaN.

Its purpose is to represent the value of "an operation that has no
mathematically definite result".  If it's not mathematically definite, it
can't be compared and it can't be equal.

So the right way to code it would be

if ( x > y )
{ ... }
else if ( x < y )
{ ... }
else if ( x == y )
{ ... }
else
{ ... }

Signature

Lew

visionset - 13 Apr 2007 17:47 GMT
>> Also, in addition to what Jaakko pointed out, you may want
>> them to be considered equal for sorting purposes
[quoted text clipped - 7 lines]
> mathematically definite result".  If it's not mathematically definite, it
> can't be compared and it can't be equal.

Lew you certainly are a Programmer.

Signature

Mike W

Larry Barowski - 13 Apr 2007 21:49 GMT
>> Also, in addition to what Jaakko pointed out, you may want
>> them to be considered equal for sorting purposes
>
> You may want them to be, but they aren't.

I think you are responding to something I have not written.
They are considered equal for sorting purposes, by
java.lang.Double for example.

> That error is the programmer's.  The programmer should not wrongly assume
> x == y in all cases, as you point out.

I never implied otherwise. I was not arguing that primitive NaNs
should compare as equal by the == operator, as you seem to be
assuming. I didn't think I gave that impression, but perhaps I was
not 100% clear.
Lew - 14 Apr 2007 00:59 GMT
> I never implied otherwise. I was not arguing that primitive NaNs
> should compare as equal by the == operator, as you seem to be
> assuming. I didn't think I gave that impression, but perhaps I was
> not 100% clear.

More likely I wasn't 100% listening.

If I understand you correctly, you want for certain purposes like sorting to
put all NaNs in the same bucket.

You could write a Comparator for Doubles that treats NaN the way you want,
then use
<http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.
List,%20java.util.Comparator
)>

Signature

Lew

julien.robinson2@gmail.com - 12 Apr 2007 13:35 GMT
> 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 <CodeFor...@gmail.com> 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
Chris Uppal - 12 Apr 2007 13:54 GMT
> 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
julien.robinson2@gmail.com - 12 Apr 2007 17:08 GMT
On Apr 12, 2:54 pm, "Chris Uppal" <chris.up...@metagnostic.REMOVE-
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
Chris Uppal - 13 Apr 2007 09:30 GMT
> 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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.