我今天遇到了一個奇怪的問題:我有把兩個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