您总是在课程中实施哪些方法和界面?
你总是重写equals()吗?如果你这样做,你也做hashcode()吗?的toString()?您是否习惯于实施Comparable接口?
我刚刚编写了一些代码,我需要实现compareTo()并覆盖equals()以使我的程序以理智的方式工作;我现在开始看到在各地使用这些的方法......
你们都在想什么?
答案 0 :(得分:13)
除非我需要,否则我通常不提前实施。
如果我的类包含数据成员并且我打算将其存储在某个地方,我通常会实现equals,hashCode和可比较的。
但是,我发现我的大部分课程都没有这个问题,所以没有必要这样做。例如,如果您的类围绕其他对象而不是数据的功能,为什么要这么麻烦?如果您有一个实例或按层次结构组织(例如,GUI小部件或窗口),为什么要这么麻烦?
不要实现你不需要的东西,但要始终确保是否需要它们,因为Java通常不会警告你。
此外,请确保使用您的IDE或Apache commons之类的东西来生成这些功能。很少需要手动编码。
至于toString,我很少实现它,直到我发现自己调试并需要在Eclipse调试器中更好的表示(例如,而不是对象ID)。我害怕隐式转换,在生成输出时从不使用toString。
答案 1 :(得分:8)
(差不多)始终toString()
。
这通常有助于调试目的。
答案 2 :(得分:4)
如果您覆盖equals
,则您(几乎总是)必须覆盖hashCode
。 hashCode
的契约是两个等于的对象必须具有相同的哈希码。如果重写equals使得相等性基于系统身份哈希码之外的某些东西,那么两个对象可能彼此相等但具有不同的哈希码。
答案 3 :(得分:3)
我认为你永远不应该实施你不需要的东西,或者不确定你是否会需要它们。如果它没有为你的代码增加价值,就不要把它放进去。如果你想让你的(单元)测试与你的代码保持同步,并用它们来显示代码的用例,那你就不应该有任何未被这些测试覆盖的东西。这包括equals(),hashCode(),compareTo()等。
除了可能浪费时间之外,我看到的问题是,它会让读取代码的人感到困惑。 “为什么这个类有等于实现?它是一些数据值吗?它可以作为集合的一部分吗?比较这个类的实例是否有意义?”
所以我说只有在你真正需要它们时才实现它们。因此,我不能说我总是实现这个和那个方法。也许toString()将是我写得最多的方法,因为它在调试中显得很有用。
答案 4 :(得分:2)
几乎总是toString(),调试和阅读有关对象的内容很痛苦Class @ 123456
在需要时使用equals()和hashCode(),但总是两者兼而有之。
Iterable接口在类似集合的类上很有用,通常只返回类似innerCollection.iterator()的东西。可比较也很有用。
另外,我们公司创建了一些我经常使用的接口,比如Displayable(比如toString,但提供更多或其他类型的信息,比如日志记录)和ParseLocatable(对于来自我们解析的文件的东西,我们想要的查看哪个文件以及哪一行例如定义了特定规则(有点像堆栈跟踪)
答案 5 :(得分:2)
Effective Java有一章介绍如何以及何时实现toString,equals,hashCode,Comparable等。强烈建议阅读。
答案 6 :(得分:0)
toString()
有时对测试目的非常有帮助,在调试时对观察也很方便。
但是我不建议在每个对象中实现Comparable
,有时它很好,但是明智地使用它或者你最终会得到大量你实际上并不需要的代码。
答案 7 :(得分:0)
同上toString()
及其在不同语言和运行时的变体,但我也想指出Ned Batchelder关于stringification的文章,这是一本很好的阅读,并且接近我的推理这样做。
答案 8 :(得分:0)
对于业务CRUD应用程序,我总是覆盖ToString。这有助于将List(Of T)绑定到WinForm控件。例如,在将Customer(Of Customer)绑定到ListBox控件时,覆盖Customer对象中的ToString以返回_name将自动显示客户名称值。派上用场。
答案 9 :(得分:0)
我通常会实施compareTo
方法以及toString
方法。通常很好知道类的一个实例如何与另一个实例进行排序和搜索。另外一个重写的toString方法非常适合调试。您可以以对您所编写的类有意义的方式查看类的内容(而不仅仅是内存位置)。
答案 10 :(得分:0)
在主要用于保存数据的对象(“rocks”)上,我发现toString和equals / hashcode契约是无价的。这是因为岩石通常一直传递到集合中并从集合中提取出来,最明显的是Hash(Set / Map)集合,它们需要equals和hashcode契约,如果toString,很容易在调试器中看到这些对象实施。在实现toString时,我总是使用Apache Common的ToStringBuilder类来显示我的所有属性 - 这样就很容易读取输出。我从不担心“隐式转换” - toString并不意味着除了人类可读的字符串之外的任何东西,toString可以在Number子类上使用以进行转换,实际上只是一个怪癖,等等。生产代码应该永远不要依赖toString方法将对象转换为字符串表示,因为这不是它的用途 - 它是用于人类可读的字符串表示,因此如果非人类,则应定义不同的方法,但是需要计算机代码可用的字符串表示。
答案 11 :(得分:0)
对于数据值类,我有一个AbstractPojo类,它使用反射来实现equals,hashCode,toString和asMap()
我为所有数据值对象扩展了这个类,所以每次都不实现它。
答案 12 :(得分:0)
我没有覆盖ToString,但我有时会应用DebuggerDisplay属性,它为调试目的执行相同操作,并且不会在发布版本上增加开销。
答案 13 :(得分:0)
我也发现自己重写了ToString()方法。尤其是在开发期间尽管代码生成器有所帮助,但每次重命名类成员时都必须更改它。 其实我很生气,我试图找到一个补救措施,这就是我想出来的:
创建此格式的字符串:MemberType MemberName = MemberValue
用法:
string testMember = "testing";
Console.WriteLine(Member.State(() => testMember));
将'string testMember =“testing”'写入控制台。 这是:
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;
}
}
可以在我的博客上找到更全面的解释以及如何使用它: Generic ToString() Method