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