cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kelven Yang <kelven.y...@citrix.com>
Subject Re: Anti-patterns
Date Tue, 25 Feb 2014 23:40:51 GMT
Having equals() and hashCode() at the same time and in consistent is
important when objects are used as keys in collections. I remember that we
ran into issues in CloudStack a long time ago when some of these basic
rules were broken

Kelven

On 2/25/14, 3:13 PM, "Mike Tutkowski" <mike.tutkowski@solidfire.com> wrote:

>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
View raw message