tags:

views:

506

answers:

14

Which methods and interfaces do you always implement in your classes?

Do you always override equals()? If you do, do you also do hashcode()? toString()? Do you make it a habit to implement the Comparable interface?

I've just written some code where I needed to implement compareTo() and override equals() to get my program to work in a sane manner; I now start seeing ways of using these everywhere...

What do y'all think?

+13  A: 

I usually don't implement things in advance unless I need them.

If my class contains data members and I plan to store it somewhere, I will usually implement equals, hashCode, and comparable.

However, I found that most of my classes do not have this issue so there's no point to do it. For example, if your class revolves around functionality on other objects rather than data, why bother? If you have one instance or is organized hierarchically (e.g., a GUI widget or window), why bother?

Don't implement things you don't need, but always make sure to check whether they are needed or not because Java will generally not warn you.

Also, make sure to use your IDE or something like Apache commons to generate these functions. There is rarely a need to hand-code them.

As for toString, I rarely implement it until I find myself debugging and needing a better presentation in the Eclipse debugger (e.g., instead of object ID). I am afraid of implicit converts and never use toString when generating output.

Uri
+8  A: 

(Almost) Always toString().

It is usually helpful for debugging purposes.

jjnguy
+4  A: 

If you override equals, you (almost always) have to override hashCode. hashCode's contract is that two objects that are equals must have the same hash code. If you override equals such that equality is based on something besides the system identity hash code, the it's possible for two objects to be equal to each other but have different hash code.

Steve Kuo
+3  A: 

I think you should never implement things you don't need, or are not sure you are going to need them or not. If it doesn't add value to your code, don't put it in. If you like to keep your (unit) tests in synch with your code, and use them to show use cases of your code, then you shouldn't have anything that is not covered by those tests. This includes equals(), hashCode(), compareTo() etc.

The problem I see, other than a possible waste of time, is that it would confuse someone who reads the code. "Why does this class have equals implemented? Is it some data value? Can it be a part of a collection? Does it even make sense to compare instances of this class?"

So I'd say only implement these when you actually need them. Therefore I can't say that I always implement this and that method. Perhaps toString() would be the method that I write the most, because it's usefulness appears a lot in debugging.

Andrei Vajna II
+1, I think this best summarises the correct approach (= always implement only what is needed)
Jonik
+2  A: 

Almost always toString(), it's a pain to be debugging and read something about object Class@123456

equals() and hashCode() when needed, but always both or neither.

The Iterable interface is useful on collection-like classes, and will usually just return something like innerCollection.iterator(). Comparable can be useful too.

also, our company created some interfaces I use a lot, like Displayable (like toString, but gives more or another type of info, like for logging) and ParseLocatable (for stuff that comes from a file we parse, and we want to see in which file and on which line where for example a specific rule was defined (a little like stacktraces)

Jorn
A: 

toString() is sometimes really helpful for testing purposes when you're too lazy to write Unit tests, also comes in handy for watches while debugging.

But I wouldn't recommend to implement Comparable in every object, it's nice sometimes, but use it wise or you'll end up with loads of code that you don't actually need.

Darth
A: 

Ditto for toString() and its variants in different languages and runtimes, but I'd also like to point you towards Ned Batchelder's article on stringification, which is a good read and is close to my reasoning for doing so.

Keith Gaughan
A: 

For business CRUD applications, I always override ToString. This helps when binding a List(Of T) to a WinForm control. For example, overriding ToString in a Customer object to return _name will then automatically show the customer name value when binding a List(Of Customer) to a ListBox control. Comes in handy.

HardCode
A: 

I usually implement the compareTo method as well as the toString method. Its generally good to know how one instance of the class compares to another instance for sorts and searches. Also an overrided toString method is great for debugging. You can see the content of the class (not just the memory location) presented in a way that makes sense for the class you have written.

zPesk
A: 

On objects that are used primarily for holding data ("rocks"), I find toString and the equals/hashcode contract to be invaluable. This is because rocks are typically passed into and extracted out of collections all the time, most notably the Hash(Set/Map) collections, which require the equals and hashcode contract, and it is very easy to see these objects in a debugger if toString is implemented. When implementing toString, I always use Apache Common's ToStringBuilder class to display all of my properties - that way it is very easy to read the output. I am never concerned about "implicit conversion" - toString is not meant to be used as anything but a human readable string, that the toString can be used on Number subclasses to convert to and from is really just a quirk, etc. Production code should never rely on the toString method to convert the object to a string representation, because that's not what it's for - it's for a human readable string representation, so a different method should be defined if a non-human, but computer code useable string representation is desired.

MetroidFan2002
+2  A: 

Effective Java has a chapter on how and when to implement toString, equals, hashCode, Comparable, etc. Highly recommended reading.

JesperE
A: 

For data value classes I have an AbstractPojo class which uses reflection to implement equals, hashCode, toString and asMap()

I extend this class for all my data value objects so I don't implement this each time.

Peter Lawrey
A: 

I don't override ToString but I apply sometimes the DebuggerDisplay attribute which does the same for the debugging purposes and does not put overhead on the release version.

Andrei Rinea
A: 

I also found myself overriding the ToString() method a lot. Especially during development. Although code generators help, it becomes quite annoying to have to change it every time you rename a class member. Actually I got so annoyed, I tried to find a remedy, This is what I came up with:

Creates a string of this format: MemberType MemberName=MemberValue

Usage:

string testMember = "testing";

Console.WriteLine(Member.State(() => testMember));

Writes ' string testMember="testing" ' to the Console. Here it is:

public static class Member
{
    public static string State<T>(Func<T> expr)
    {
        var member = ExtractMemberFromLambdaExpression(expr);

        Type memberType = GetTypeOfMember(member);

        string contents = ExtractContentsFromLambdaExpression(expr);

        return string.Format("{0} {1}={2}",memberType.Name,  member.Name, contents);
    }

    static string ExtractContentsFromLambdaExpression<T>(Func<T> expr)
    {
        if (expr() == null) {
            return "NULL";
        }

        string contents = string.Empty;
        if (expr().GetType().IsArray) {
            foreach (var item in (expr() as Array)) {
                contents += item.ToStringNullSafe() + ", ";
            }
            contents = contents.Trim().TrimEnd(',');
        } else {
            contents = expr().ToString();
        }

        return contents;
    }

    static MemberInfo ExtractMemberFromLambdaExpression<T>(Func<T> expr)
    {
        // get IL code behind the delegate
        var il = expr.Method.GetMethodBody().GetILAsByteArray();
        // bytes 2-6 represent the member handle
        var memberHandle = BitConverter.ToInt32(il, 2);
        // resolve the handle
        return expr.Target.GetType().Module.ResolveMember(memberHandle);
    }


    static Type GetTypeOfMember(MemberInfo member)
    {
        Type memberType;
        if (member.MemberType == MemberTypes.Field) {
            memberType = GetFieldType(member as FieldInfo);
        }
        else if (member.MemberType == MemberTypes.Property) {
            memberType = GetPropertyType(member as PropertyInfo);
        }
        else {
            memberType = typeof(object);
        }
        return memberType;
    }

    static Type GetFieldType(FieldInfo fieldInfo)
    {
        return fieldInfo.FieldType;
    }

    static Type GetPropertyType(PropertyInfo propertyInfo)
    {
        return propertyInfo.PropertyType;
    }
}

A more thorough explanation and how to use it can be found on my blog about the: Generic ToString() Method

Thorsten Lorenz