diff --git a/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java b/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java
index da17bd29..0b3ebfdd 100644
--- a/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java
+++ b/spring-geode/src/main/java/org/springframework/geode/core/util/ObjectUtils.java
@@ -27,6 +27,7 @@ import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.function.Supplier;
import org.apache.geode.pdx.PdxInstance;
@@ -258,6 +259,33 @@ public abstract class ObjectUtils extends org.springframework.util.ObjectUtils {
return doOperationSafely(() -> (T) field.get(obj), (T) null);
}
+ /**
+ * An initialization operator used to evalutate a given {@link Object target} and conditionally
+ * {@link Supplier supply} a new value if the {@link Object target} is {@literal null}.
+ *
+ * The {@code initialize} operator simplifies a common initialization safety pattern that appears in code as:
+ *
+ *
+ * target = target != null ? target : new Target();
+ *
+ *
+ * While the expression uses Java's ternary operator, users could very well use a if-then-else statement instead.
+ * Either way, since Java is {@literal call-by-value} then the above statement and expression can be replaced with:
+ *
+ *
+ * target = initialize(target, Target::new);
+ *
+ *
+ * @param {@link Class type} of the {@link Object target}.
+ * @param target {@link Object} to evaluate and initialize; must not be {@literal null}.
+ * @param supplier {@link Supplier} used to initialize the {@link Object target} on return.
+ * @return the existing {@link Object target} if not {@literal null}, otherwise invoke the {@link Supplier}
+ * to supply a new instance of {@link T}.
+ */
+ public static T initialize(@Nullable T target, @NonNull Supplier supplier) {
+ return target != null ? target : supplier.get();
+ }
+
/**
* Invokes a {@link Method} on an {@link Object} with the given {@link String name}.
*
@@ -281,13 +309,27 @@ public abstract class ObjectUtils extends org.springframework.util.ObjectUtils {
methodName, org.springframework.util.ObjectUtils.nullSafeClassName(obj)));
}
- public static Constructor makeAccessible(Constructor> constructor) {
+ /**
+ * Makes the {@link Constructor} accessible.
+ *
+ * @param constructor {@link Constructor} to make accessible; must not be {@literal null}.
+ * @return the given {@link Constructor}.
+ * @see java.lang.reflect.Constructor
+ */
+ public static Constructor makeAccessible(@NonNull Constructor> constructor) {
ReflectionUtils.makeAccessible(constructor);
return constructor;
}
+ /**
+ * Makes the {@link Field} accessible.
+ *
+ * @param field {@link Field} to make accessible; must not be {@literal null}.
+ * @return the given {@link Field}.
+ * @see java.lang.reflect.Field
+ */
public static Field makeAccessible(Field field) {
ReflectionUtils.makeAccessible(field);
@@ -295,6 +337,13 @@ public abstract class ObjectUtils extends org.springframework.util.ObjectUtils {
return field;
}
+ /**
+ * Makes the {@link Method} accessible.
+ *
+ * @param constructor {@link Method} to make accessible; must not be {@literal null}.
+ * @return the given {@link Method}.
+ * @see java.lang.reflect.Method
+ */
public static Method makeAccessible(Method method) {
ReflectionUtils.makeAccessible(method);
diff --git a/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java b/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java
index 9f8de780..2c3d6a01 100644
--- a/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java
+++ b/spring-geode/src/test/java/org/springframework/geode/core/util/ObjectUtilsUnitTests.java
@@ -95,7 +95,7 @@ public class ObjectUtilsUnitTests {
}
@Test(expected = IllegalArgumentException.class)
- public void asPdxInstanceTypeReturnNonMatchingType() {
+ public void asPdxInstanceTypeReturningNonMatchingType() {
C source = new C();
@@ -300,6 +300,16 @@ public class ObjectUtilsUnitTests {
}
}
+ @Test
+ public void initializeWithNonNullTarget() {
+ assertThat(ObjectUtils.initialize("test", () -> "mock")).isEqualTo("test");
+ }
+
+ @Test
+ public void initializeWithNullTarget() {
+ assertThat(ObjectUtils.initialize(null, () -> "mock")).isEqualTo("mock");
+ }
+
@Test
public void invokeMethodOnObjectReturnsValue() {
assertThat(ObjectUtils.invoke(new TestObject(), "testMethod")).isEqualTo("TEST");