Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/netserializer/SerDes.java
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,12 @@ private <T extends Serializable> TypeReaderWriter<T> makeClassReaderWriter(final
final List<FieldInfo> persistentFields = new ArrayList<>();
for (Field f: fields) {
int modifiers = f.getModifiers();
if (!Modifier.isFinal(modifiers) && !Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {

//v1.1: Allow serialization of final fields.
//Setting final fields via reflection may give weird results if the
//field is a compile-time constant, but if it is, it will never have
//a different value anyway, so this is not an issue.
if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {

//If the field's compile-time type is primitive, it is possible
//to omit the runtime object type since the runtime type will
Expand Down
57 changes: 55 additions & 2 deletions unittests/netserializer/SerDesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,41 @@ public static TestClassMap getInstance() {
}
}

class TestClassFinalField implements Serializable {
public final int i1;
public final Integer i2;

//Compile-time constant
public final String str = "abc";

public TestClassFinalField() {
i1 = 99;
i2 = 3;
}

public TestClassFinalField(int i1, Integer i2) {
this.i1 = i1;
this.i2 = i2;
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!this.getClass().equals(obj.getClass())) {
return false;
}
TestClassFinalField other = (TestClassFinalField)obj;
return (this.i1 == other.i1) && this.i2.equals(other.i2) && this.str.equals(other.str);
}

@Override
public int hashCode() {
return Integer.hashCode(i1) + this.i2.hashCode() + str.hashCode();
}
}

public class SerDesTest {

private SerDes writer;
Expand All @@ -218,7 +253,8 @@ private SerDes makeSerDes() throws NoSuchMethodException, SecurityException {
TestClassComposed.class,
TestClassBoxedPrimitive.class,
TestClassListAndSet.class,
TestClassMap.class));
TestClassMap.class,
TestClassFinalField.class));
}

@Before
Expand Down Expand Up @@ -319,14 +355,31 @@ public void testNull() throws Exception {
testWith(null);
}

/**
* Tests serialization of final fields.
*
* @throws Exception
*/
@Test
public void testFinalFields() throws Exception {
String whatItShouldBe = new TestClassFinalField().str;

TestClassFinalField obj = (TestClassFinalField)testWith(new TestClassFinalField());
assertTrue(obj.str.equals(whatItShouldBe));

obj = (TestClassFinalField)testWith(new TestClassFinalField(5, 87));
assertTrue(obj.str.equals(whatItShouldBe));
}


private void testWith(Object obj) throws Exception {
private Object testWith(Object obj) throws Exception {
Object result = this.serializeAndDeserialize(obj, writer, reader);
if (obj != null) {
assertTrue(obj.equals(result));
} else {
assertTrue(result == null);
}
return result;
}

private Object serializeAndDeserialize(Object obj, SerDes writer, SerDes reader) throws Exception {
Expand Down