Skip to content

Commit 90d0620

Browse files
committed
#159 Processes non-static fields before static fields so static fields don't obscure issues in non-static fields
1 parent 50ae101 commit 90d0620

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
## [Unreleased]
1414
### Changed
1515
- Added more helpful error message explaining why EqualsVerifier can't verify subclasses of `java.util.ArrayList`. ([Issue 341](https://github.com/jqno/equalsverifier/issues/341))
16+
- Changes order of processing fields (non-statics first, statics later) so static fields don't obscure issues that are really in non-static fields. ([Issue 159](https://github.com/jqno/equalsverifier/issues/159))
1617

1718
### Fixed
1819
- Added prefab values for `java.net.URL`. ([Issue 340](https://github.com/jqno/equalsverifier/issues/340))

src/main/java/nl/jqno/equalsverifier/internal/reflection/FieldIterable.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package nl.jqno.equalsverifier.internal.reflection;
22

33
import java.lang.reflect.Field;
4+
import java.lang.reflect.Modifier;
45
import java.util.ArrayList;
56
import java.util.Iterator;
67
import java.util.List;
@@ -66,14 +67,22 @@ private List<Field> createFieldList() {
6667
}
6768

6869
private List<Field> addFieldsFor(Class<?> c) {
69-
List<Field> result = new ArrayList<>();
70+
List<Field> fields = new ArrayList<>();
71+
List<Field> statics = new ArrayList<>();
7072

7173
for (Field field : c.getDeclaredFields()) {
7274
if (!field.isSynthetic() && !"__cobertura_counters".equals(field.getName())) {
73-
result.add(field);
75+
if (Modifier.isStatic(field.getModifiers())) {
76+
statics.add(field);
77+
} else {
78+
fields.add(field);
79+
}
7480
}
7581
}
7682

83+
List<Field> result = new ArrayList<>();
84+
result.addAll(fields);
85+
result.addAll(statics);
7786
return result;
7887
}
7988
}

src/test/java/nl/jqno/equalsverifier/integration/extended_contract/SignificantFieldsTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,15 @@ public void fail_whenNonNullFieldIsEqualToNullField() {
324324
EqualsVerifier.forClass(BugWhenFieldIsNull.class).verify();
325325
}
326326

327+
@Test
328+
public void giveCorrectMessage_whenStaticFieldIsNotUsed_givenStaticFieldIsFirstField() {
329+
// See https://github.com/jqno/equalsverifier/issues/159
330+
expectFailure("Significant fields", "equals does not use i");
331+
EqualsVerifier.forClass(IdentityIntContainer.class)
332+
.suppress(Warning.IDENTICAL_COPY)
333+
.verify();
334+
}
335+
327336
static final class ConstantHashCode {
328337
private final int x;
329338
private final int y;
@@ -686,4 +695,23 @@ public int hashCode() {
686695
return Objects.hashCode(s);
687696
}
688697
}
698+
699+
public static final class IdentityIntContainer {
700+
public static final int WHATEVER = 1;
701+
private final int i;
702+
703+
private IdentityIntContainer(int i) {
704+
this.i = i;
705+
}
706+
707+
@Override
708+
public boolean equals(Object obj) {
709+
return super.equals(obj);
710+
}
711+
712+
@Override
713+
public int hashCode() {
714+
return i;
715+
}
716+
}
689717
}

src/test/java/nl/jqno/equalsverifier/internal/reflection/FieldIterableTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ public void classInTheMiddleHasNoFields() throws NoSuchFieldException {
9292
assertEquals(expected, actual);
9393
}
9494

95+
@Test
96+
public void orderingTest() {
97+
FieldIterable iterable = FieldIterable.of(UnorderedFieldContainer.class);
98+
List<String> actual = new ArrayList<>();
99+
for (Field f : iterable) {
100+
actual.add(f.getName());
101+
}
102+
103+
assertEquals(Arrays.asList("one", "two", "THREE", "FOUR"), actual);
104+
}
105+
95106
@Test
96107
public void interfaceTest() {
97108
FieldIterable iterable = FieldIterable.of(Interface.class);

src/test/java/nl/jqno/equalsverifier/testhelpers/types/TypeHelper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ public static class SubEmptySubFieldContainer extends EmptySubFieldContainer {
169169
public long field = 0;
170170
}
171171

172+
@SuppressWarnings("unused")
173+
public static class UnorderedFieldContainer {
174+
public static final int THREE = 3;
175+
public final int one = 1;
176+
private static final int FOUR = 4;
177+
private final int two = 2;
178+
}
179+
172180
public interface Interface {}
173181

174182
public abstract static class AbstractClass {

0 commit comments

Comments
 (0)