我今天遇到了一个奇怪的问题:我有把两个Date对象作为参数的方法。调用方法通过引用与它们两者相同的对象(所讨论的方法是EqualsBuilder.append)。第一个参数通过很好,但第二个参数没有。这是一个新的Date对象,这是从意义上的第一个,除了年月日之间的所有字段都设置为0。注意,我没有说会复制对象的任何代码,不同的...是JVM中的错误?为什么将它传递给一个方法时,JVM创建对象的副本?
的代码是相当简单明了,我只注意到,因为我的单元测试上的东西应该是非常相同的对象比较失败(我用一些随机的长初始化它)。
编辑:
- 我不相信自己...
- 我没有承担JVM错误,我硬是花了4小时这段代码盯着调试它。
- 我看着在调试器来验证它们是同一个对象(也将与调用方法==测试星期一)。
- 我在Windows XP上使用1.6.0_17
- 我无法在第二秒发布实际代码,星期一就会这样做。
编辑2:
- 。重新启动Eclipse之后,我无法重现错误
- 我有7名目击者可以证明,它发生了:)
- 这些证人说这在以前的演出,他们在3年内
- 因此遇到事情到那种程度,他们遇到了这个错误(或怪异的行为)一次,我想,我的胜算reproducin的克形势相当渺茫(我真希望我没采取截图)
编辑3:
下面是有问题的类代码:
进口的java.util 。日期; import java.util.List;
import org.apache.commons.lang.builder.EqualsBuilder; 进口org.apache.commons.lang.builder.HashCodeBuilder;
公共类Foo {
private final long roadId;
private final Date creationDate;
private final Date editDate;
private final List<String> vehicleTypes;
private final boolean continuous;
public Foo(final long roadId, final Date creationDate, final Date editDate, final List<String> vehicleTypes, final boolean continuous) {
super();
this.roadId = roadId;
this.creationDate = creationDate;
this.editDate = editDate;
this.vehicleTypes = vehicleTypes;
this.continuous = continuous;
}
public long getRoadId() {
return roadId;
}
public Date getCreationDate() {
return creationDate;
}
public Date getEditDate() {
return editDate;
}
public List<String> getVehicleTypes() {
return vehicleTypes;
}
public boolean isContinuous() {
return this.continuous;
}
@Override
public int hashCode() {
final HashCodeBuilder builder = new HashCodeBuilder();
builder.append(this.roadId);
builder.append(this.creationDate);
builder.append(this.editDate);
builder.append(this.vehicleTypes);
builder.append(this.continuous);
return builder.toHashCode();
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Foo)) {
return false;
}
final Foo other = (Foo)obj;
EqualsBuilder builder = new EqualsBuilder();
builder.append(this.roadId, other.roadId);
builder.append(this.creationDate, other.creationDate);
builder.append(this.editDate, other.editDate);
builder.append(this.vehicleTypes, other.vehicleTypes);
builder.append(this.continuous, other.continuous);
return builder.isEquals();
}
}
- 而失败的单元测试: 进口java.util.Arrays中; import java.util.Date; import java.util。清单;
进口静态org.junit.Assert *。 import org.junit.Before; import org.junit.Test;
公共类FooTest {
private static final boolean CONTINUOUS = true;
private static final Date CREATION_DATE = new Date(12345678901L);
private static final Date EDIT_DATE = new Date(987654321654321L);
private static final long ROAD_ID = 101;
private static final List<String> VEHICLE_TYPES = Arrays.<String> asList("TEST");
private Foo nonEmpty;
private Foo otherNonEmpty;
@Before
public void setUp() {
this.nonEmpty = new Foo(FooTest.ROAD_ID, FooTest.CREATION_DATE,
FooTest.EDIT_DATE, FooTest.VEHICLE_TYPES, true);
this.otherNonEmpty = new Foo(FooTest.ROAD_ID, FooTest.CREATION_DATE,
FooTest.EDIT_DATE, FooTest.VEHICLE_TYPES, FooTest.CONTINUOUS);
}
@Test
public void testEquals() {
assertTrue(this.nonEmpty.equals(this.otherNonEmpty));
}
}
现在,如果我改变了这一点:
private static final Date CREATION_DATE = new Date(12345678901L);
private static final Date EDIT_DATE = new Date(987654321654321L);
这样:
private static final Date CREATION_DATE = new Date(109,1,11);
private static final Date EDIT_DATE = new Date(110,3,13);
它工作得很好。
我不认为该代码是错误的,特别是在重新启动之后,JVM所有测试通过。同时,我知道JVM中存在一个错误的可能性很小(尽管它是一个软件,没有软件是没有bug的)。
现在我在构造函数中的代码,首先导致的错误检查了,也许我将有幸再次遇到。感谢您的反馈。
要发布代码将比尝试描述它更加清晰。 – 2009-12-04 22:19:04
我不相信。我同意@Jonathan Feinberg。让我们看看代码。 – bmargulies 2009-12-04 22:20:42
我第三。让我们看看一些代码。 – 2009-12-04 22:32:44