First off, please bear with me. Most of the time I am working in Scala (and only sometimes on the JVM side) or other languages, so my Java (8) knowledge is a bit limited!
Code I have to refactor is littered with null checks. I wanted to make the setting/overriding of some pojo's attributes a bit nicer and got excited being able to use Java 8 for the job.
So I created this:
private <T> void setOnlyIfNotNull(final T newValue, Consumer<T> setter) {
if(newValue != null) {
setter.accept(newValue);
}
}
And used it like this:
setOnlyIfNotNull(newUserName, user::setName);
The junit4-test looks like this:
@Test
public void userName_isOnlyUpdated_ifProvided() {
User user = new User("oldUserName");
UserUpdateRequest request = new UserUpdateRequest().withUserName("newUserName");
service.updateUser(user, request); // This calls setOnlyIfNotNull behind the curtain. And it does invoke the setter ONLY once!
assertThat(user.getUserName()).isEqualTo("newUserName");
}
And this works. I was quite content with myself until I asked a colleague for a code review. Upon explaining what I did he elaborated that he thought this could not work, as functions are still no first class citizens in Java AND the User-pojo did not extend a FunctionalInterface. Also interfaces are provided on class level, not function level.
Now I wonder, why does the test work and am I misusing something here? Naive me simply imagined that the Java compiler knew that a setter's T setT(T value)
signature was the same as for a Consumer<T>
.
edit: To elaborate a bit more: If I change the test to fail e.g. with assertThat(user.getUserName()).isEqualTo("Something");
it fails with a comparisonFailure as expected!