cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Tutkowski <mike.tutkow...@solidfire.com>
Subject Re: Anti-patterns
Date Tue, 25 Feb 2014 23:13:42 GMT
This is a good summary of the equals and hashCode methods:


   1. If object1 and object2 are equal according to their equals() method,
   they must also have the same hash code.
   2. If object1 and object2 have the same hash code, they do NOT have to
   be equal too.

>From http://tutorials.jenkov.com/java-collections/hashcode-equals.html


On Tue, Feb 25, 2014 at 3:07 PM, Marcus <shadowsor@gmail.com> wrote:

> Also keep in mind that with an Object or custom objects that extend it,
> doing
>
>     if (obj.equals(thing))
>
> is usually the same as:
>
>     if (obj == thing)
>
> Since the Object.equals() method by default says something like:
>
>     public boolean equals(Object other)
>     {
>         return this == other;
>     }
>
> Unless it is overridden, (along with hashCode() from what I
> understand, since Objects deemed 'equal' are supposed to return the
> same hash). So the issue may partially be due to the fact that those
> are largely equivalent in many objects, but not in objects like
> Integer which presumably do something different in their equals()
> implementation. When something works as expected in other
> circumstances it's understandable that the mistake would be made.
>
> I actually fixed a bug recently with resource tags that dealt with
> this, a listVirtualMachines call would duplicate the resource tags,
> sometimes printing up to 8 of the same tag, because someone had done
> "if(!tag1.equals(tag2))", or something expecting to filter duplicates.
> To fix I just implemented the equals() and hashCode() for the resource
> tag object.
>
>
> On Tue, Feb 25, 2014 at 12:19 PM, Suresh Sadhu <Suresh.Sadhu@citrix.com>
> wrote:
> > Thanks Hugo for sharing  this valuable  info.
> >
> > And also  it provides "Different" output  when value  crosses the Int
> range
> >
> > public class App
> > {
> >         public static void main(String[] args)
> >         {
> >                 Integer a = 128;
> >                 Integer b = 128;
> >
> >                 if (a == b) {
> >                         System.out.println("Equal!");
> >                 } else {
> >                         System.out.println("Different!");
> >                 }
> >         }
> > }
> >
> > Output:Different.
> >
> > Regards
> > Sadhu
> >
> >
> >
> >
> > -----Original Message-----
> > From: Min Chen [mailto:min.chen@citrix.com]
> > Sent: 25 February 2014 23:08
> > To: dev@cloudstack.apache.org
> > Subject: Re: Anti-patterns
> >
> > Thanks Hugo for the nice tutorial. In the last example, are you trying
> to saying this (luckily this time == works although not recommended)
> >
> > public class App
> > {
> >         public static void main(String[] args)
> >         {
> >                 Integer a = 1;
> >                 Integer b = 1;
> >
> >                 if (a == b) {
> >                         System.out.println("Equal!");
> >                 } else {
> >                         System.out.println("Different!");
> >                 }
> >         }
> > }
> >
> > -min
> >
> >
> >
> >
> > On 2/25/14 5:41 AM, "Hugo Trippaers" <hugo@trippaers.nl> wrote:
> >
> >>Anti-pattern:
> >>An anti-pattern (or antipattern) is a common response to a recurring
> >>problem that is usually ineffective and risks being highly
> >>counterproductive. The term, coined in 1995 by Andrew Koenig, was
> >>inspired by a book, Design Patterns, in which the authors highlighted a
> >>number of design patterns in software development that they considered
> >>to be highly reliable and effective.
> >>< source http://en.wikipedia.org/wiki/Anti-pattern
> >>
> >>
> >>Here at Schuberg we spend quite some time going through bugs reports
> >>from automated scanners, you have probably seen the mails coming by on
> the ML.
> >>As part of our work we have encountered a number of problems that keep
> >>on popping up in the code base. So here is my first attempt to clarify
> >>why a certain pattern is wrong and hopefully help developers to avoid
> this.
> >>
> >>So first up is the equality operator, ==.  This operator is commonly
> >>used in many languages to compare if two items are equal. The trick
> >>with this operator in java is to know exactly what you are comparing,
> >>because it matters.
> >>
> >>Consider this piece of code:
> >>
> >>public class App
> >>{
> >>    public static void main(String[] args)
> >>    {
> >>        int a = 1;
> >>        int b = 1;
> >>
> >>        if (a == b) {
> >>            System.out.println("Equal!");
> >>        } else {
> >>            System.out.println("Different!");
> >>        }
> >>    }
> >>}
> >>
> >>The expected outcome is ³Equal!² and indeed it prints just that. Now
> >>consider the following code:
> >>
> >>public class App
> >>{
> >>    public static void main(String[] args)
> >>    {
> >>        Integer a = new Integer(1);
> >>        Integer b = new Integer(1);
> >>
> >>        if (a == b) {
> >>            System.out.println("Equal!");
> >>        } else {
> >>            System.out.println("Different!");
> >>        }
> >>    }
> >>}
> >>
> >>The result of running this bit of code is ³Different!². With == you are
> >>telling the java compiler to compare the two variables. The variable
> >>are references to Objects, so it will do exactly what you tell it to
> >>do, compare the two object references. As you give it two different
> >>objects, the result willl be ³Different!². The correct way of comparing
> >>the contents of two objects is to use the equals method. Consider the
> >>following piece of code:
> >>
> >>public class App
> >>{
> >>    public static void main(String[] args)
> >>    {
> >>        Integer a = new Integer(1);
> >>        Integer b = new Integer(1);
> >>
> >>        if (a.equals(b)) {
> >>            System.out.println("Equal!");
> >>        } else {
> >>            System.out.println("Different!");
> >>        }
> >>    }
> >>}
> >>
> >>
> >>This will again be ³Equals!².
> >>
> >>Why is this often a problem? There are a lot or reasons why these bugs
> >>came to exist in CloudStack (or any other project). For example
> >>somebody might cause this bug by changing the return type of a function
> >>from long to Long. The first one is a primitive which can be compared
> >>with == and the second one is an Object which might result in another
> >>comparison than you intended. Findbugs will catch these types of
> >>comparisons and warn you for them. See commit
> >>d1efdca50622a0b67ae1a286aad3297b1c748e9e for an example.
> >>
> >>
> >>
> >>Oh and what does this print?
> >>
> >>public class App
> >>{
> >>    public static void main(String[] args)
> >>    {
> >>        Integer a = 1;
> >>        Integer b = 1;
> >>
> >>        if (a.equals(b)) {
> >>            System.out.println("Equal!");
> >>        } else {
> >>            System.out.println("Different!");
> >>        }
> >>    }
> >>}
> >>
> >>
> >>Surprise!, it prints ³Equals!².  This is a boxed integer and java keeps
> >>a pool of these so internally the object is cached and both a and b get
> >>the same objects assigned to them by the internal boxing logic. Just
> >>never rely on this! It only works in specific cases and is
> >>implementation specific per JVM vendor and JVM version.
> >>
> >>Cheers,
> >>
> >>Hugo
> >>
> >>
> >>P.S. If you have another anti pattern feel free to post em in this
> thread.
> >>
> >
>



-- 
*Mike Tutkowski*
*Senior CloudStack Developer, SolidFire Inc.*
e: mike.tutkowski@solidfire.com
o: 303.746.7302
Advancing the way the world uses the
cloud<http://solidfire.com/solution/overview/?video=play>
*(tm)*

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message