Java 您(几乎)总是在类中实现哪些方法和接口?

Java 您(几乎)总是在类中实现哪些方法和接口?,java,Java,您总是在类中实现哪些方法和接口 是否总是重写equals()?如果您这样做,您是否也执行hashcode()?toString()?您是否养成了实现类似接口的习惯 我刚刚编写了一些代码,需要实现compareTo()和override equals(),以使程序正常工作;我现在开始发现在任何地方使用这些的方法 你们怎么想?除非我需要,否则我通常不会提前实施 如果我的类包含数据成员,并且我计划将其存储在某个地方,我通常会实现equals、hashCode和comparable 但是,我发现我的大多

您总是在类中实现哪些方法和接口

是否总是重写equals()?如果您这样做,您是否也执行hashcode()?toString()?您是否养成了实现类似接口的习惯

我刚刚编写了一些代码,需要实现compareTo()和override equals(),以使程序正常工作;我现在开始发现在任何地方使用这些的方法


你们怎么想?

除非我需要,否则我通常不会提前实施

如果我的类包含数据成员,并且我计划将其存储在某个地方,我通常会实现equals、hashCode和comparable

但是,我发现我的大多数类都没有这个问题,所以没有必要这样做。例如,如果您的类围绕其他对象上的功能而不是数据,那么为什么还要麻烦呢?如果您有一个实例或是按层次结构组织的(例如,GUI小部件或窗口),为什么要麻烦呢

不要实现您不需要的东西,但始终确保检查它们是否需要,因为Java通常不会警告您

另外,确保使用IDE或类似ApacheCommons的东西来生成这些函数。很少需要手工编写代码

至于toString,我很少实现它,直到我发现自己正在调试并且需要在Eclipse调试器中有更好的表示(例如,代替对象ID)。我害怕隐式转换,在生成输出时从不使用toString

(几乎)总是
toString()


它通常有助于调试。

如果覆盖
等于
,则(几乎总是)必须覆盖
hashCode
hashCode
的约定是两个相等的对象必须具有相同的哈希代码。如果您重写equals,使得equality基于系统标识哈希代码之外的内容,那么两个对象可能彼此相等,但具有不同的哈希代码。

我认为您永远不应该实现不需要的东西,或者不确定是否需要它们。如果它不能给你的代码增加价值,就不要把它放进去。如果您希望使(单元)测试与代码保持同步,并使用它们来显示代码的用例,那么您不应该有那些测试未涵盖的内容。这包括equals()、hashCode()、compareTo()等

我看到的问题,除了可能浪费时间之外,是它会让阅读代码的人感到困惑。“为什么这个类实现了equals?它是一些数据值吗?它可以是集合的一部分吗?比较这个类的实例是否有意义?”

所以我想说,只有在你真正需要的时候才能实现这些。因此,我不能说我总是实现这个和那个方法。也许toString()是我写得最多的方法,因为它在调试中非常有用。

几乎总是toString(),调试和阅读有关对象的内容是一件痛苦的事情Class@123456

需要时等于()和hashCode(),但总是两者都有或两者都没有

Iterable接口对类似集合的类很有用,通常只返回innerCollection.iterator()之类的内容。可比性也很有用

此外,我们公司创建了一些我经常使用的接口,比如Displayable(比如toString,但提供更多或其他类型的信息,比如日志记录)和ParseLocatable(对于来自我们解析的文件的内容,我们希望看到在哪个文件和哪行定义了特定规则(有点像stacktraces)

toString()
有时在您懒得编写单元测试的情况下对测试非常有用,在调试时也可以方便地查看


但我不建议在每个对象中都实现
Comparable
,有时这很好,但要明智地使用它,否则最终会得到大量实际上不需要的代码。

toString()相同
及其在不同语言和运行时的变体,但我还想向您介绍Ned Batchelder的文章,这篇文章读得很好,接近我这样做的理由。

对于业务CRUD应用程序,我总是覆盖ToString。这在绑定列表(T)时很有帮助例如,在客户对象中重写ToString以返回_name将在绑定(客户)列表时自动显示客户名称值我通常实现
compareTo
方法以及
toString
方法。通常,了解类的一个实例如何与另一个实例进行排序和搜索比较是很好的。重写的toString方法对于调试也很好。您可以看到cla的内容ss(不仅仅是内存位置)的显示方式对您编写的类有意义。

主要用于保存数据的对象(“岩石”),我发现toString和equals/hashcode契约是非常宝贵的。这是因为岩石通常总是被传递到集合中或从集合中提取出来,最明显的是散列(Set/Map)集合,它需要equals和hashcode协定,如果实现了toString,在调试器中很容易看到这些对象。在实现toString时,我总是使用Apache Common的toString Builder类来显示我的所有属性,这样就很容易读取输出。我从不担心“隐式转换"-toString只能用作人类可读的字符串,toString可以用于数字子类进行转换,这实际上只是一个怪癖,等等。生产代码永远不应该依赖toString方法将对象转换为字符串表示,因为这不是它的用途-它是用于人类可读的字符串表示法
string testMember = "testing";

Console.WriteLine(Member.State(() => testMember));
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;
    }
}