Skip to content

Commit 5361053

Browse files
committed
#100 Introduce ClassUtils#tryCast
1 parent a5baae3 commit 5361053

File tree

2 files changed

+74
-26
lines changed

2 files changed

+74
-26
lines changed

Diff for: src/main/java/ch/jalu/typeresolver/classutil/ClassUtils.java

+17
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,23 @@ public static Class<?> loadClassOrThrow(String name) {
5959
}
6060
}
6161

62+
/**
63+
* Returns an optional with the given object cast to the target type, or an empty optional if the given object
64+
* cannot be cast to the specified type.
65+
*
66+
* @param object the object to cast
67+
* @param targetType the class to cast to
68+
* @param <T> target type
69+
* @return optional with the cast object, or empty optional if not possible
70+
*/
71+
@SuppressWarnings("unchecked")
72+
public static <T> Optional<T> tryCast(@Nullable Object object, Class<T> targetType) {
73+
if (targetType.isInstance(object)) {
74+
return Optional.of((T) object);
75+
}
76+
return Optional.empty();
77+
}
78+
6279
/**
6380
* Returns an Optional with the same class cast as subtype of the given {@code parent} if possible,
6481
* otherwise returns an empty optional.

Diff for: src/test/java/ch/jalu/typeresolver/classutil/ClassUtilsTest.java

+57-26
Original file line numberDiff line numberDiff line change
@@ -98,34 +98,65 @@ void shouldLoadClassOrThrowException() {
9898
}
9999
}
100100

101-
@Test
102-
void shouldCastClassAsSubclass() {
103-
// given / when
104-
Optional<Class<? extends CharSequence>> result1 = ClassUtils.asSubclassIfPossible(String.class, CharSequence.class);
105-
Optional<Class<? extends Number>> result2 = ClassUtils.asSubclassIfPossible(Integer.class, Number.class);
106-
Optional<Class<? extends Serializable>> result3 = ClassUtils.asSubclassIfPossible(Integer.class, Serializable.class);
107-
Optional<Class<? extends Number[]>> result4 = ClassUtils.asSubclassIfPossible(Integer[].class, Number[].class);
108-
Optional<Class<? extends Double>> result5 = ClassUtils.asSubclassIfPossible(Double.class, Double.class);
109-
Optional<Class<? extends Integer>> result6 = ClassUtils.asSubclassIfPossible(int.class, int.class);
110-
111-
// then
112-
assertThat(result1, equalTo(Optional.of(String.class)));
113-
assertThat(result2, equalTo(Optional.of(Integer.class)));
114-
assertThat(result3, equalTo(Optional.of(Integer.class)));
115-
assertThat(result4, equalTo(Optional.of(Integer[].class)));
116-
assertThat(result5, equalTo(Optional.of(Double.class)));
117-
assertThat(result6, equalTo(Optional.of(int.class)));
118-
}
101+
@Nested
102+
class SubClassAndCastingUtils {
119103

120-
@Test
121-
void shouldNotCastAsSubclassWhenNotPossible() {
122-
// given / when / then
123-
assertThat(ClassUtils.asSubclassIfPossible(String.class, Number.class), equalTo(Optional.empty()));
124-
assertThat(ClassUtils.asSubclassIfPossible(Number.class, Integer.class), equalTo(Optional.empty()));
125-
assertThat(ClassUtils.asSubclassIfPossible(Integer[].class, CharSequence[].class), equalTo(Optional.empty()));
104+
@Test
105+
void shouldCastToTargetType() {
106+
// given / when
107+
Optional<Number> result1 = ClassUtils.tryCast(3, Number.class);
108+
Optional<String> result2 = ClassUtils.tryCast("str", String.class);
109+
Optional<Serializable> result3 = ClassUtils.tryCast("str", Serializable.class);
110+
Integer[] integerArray = {1, 2, 3};
111+
Optional<Number[]> result4 = ClassUtils.tryCast(integerArray, Number[].class);
112+
113+
// then
114+
assertThat(result1, equalTo(Optional.of(3)));
115+
assertThat(result2, equalTo(Optional.of("str")));
116+
assertThat(result3, equalTo(Optional.of("str")));
117+
assertThat(result4, equalTo(Optional.of(integerArray)));
118+
}
119+
120+
@Test
121+
void shouldNotCastObjectWhenNotPossible() {
122+
// given / when / then
123+
assertThat(ClassUtils.tryCast(3, String.class), equalTo(Optional.empty()));
124+
assertThat(ClassUtils.tryCast("str", Character[].class), equalTo(Optional.empty()));
125+
assertThat(ClassUtils.tryCast(null, Number.class), equalTo(Optional.empty()));
126126

127-
assertThat(ClassUtils.asSubclassIfPossible(int.class, Integer.class), equalTo(Optional.empty()));
128-
assertThat(ClassUtils.asSubclassIfPossible(Integer.class, int.class), equalTo(Optional.empty()));
127+
// Special case Integer <-> int: Integer is not considered an int.class
128+
assertThat(ClassUtils.tryCast(3, int.class), equalTo(Optional.empty()));
129+
}
130+
131+
@Test
132+
void shouldCastClassAsSubclass() {
133+
// given / when
134+
Optional<Class<? extends CharSequence>> result1 = ClassUtils.asSubclassIfPossible(String.class, CharSequence.class);
135+
Optional<Class<? extends Number>> result2 = ClassUtils.asSubclassIfPossible(Integer.class, Number.class);
136+
Optional<Class<? extends Serializable>> result3 = ClassUtils.asSubclassIfPossible(Integer.class, Serializable.class);
137+
Optional<Class<? extends Number[]>> result4 = ClassUtils.asSubclassIfPossible(Integer[].class, Number[].class);
138+
Optional<Class<? extends Double>> result5 = ClassUtils.asSubclassIfPossible(Double.class, Double.class);
139+
Optional<Class<? extends Integer>> result6 = ClassUtils.asSubclassIfPossible(int.class, int.class);
140+
141+
// then
142+
assertThat(result1, equalTo(Optional.of(String.class)));
143+
assertThat(result2, equalTo(Optional.of(Integer.class)));
144+
assertThat(result3, equalTo(Optional.of(Integer.class)));
145+
assertThat(result4, equalTo(Optional.of(Integer[].class)));
146+
assertThat(result5, equalTo(Optional.of(Double.class)));
147+
assertThat(result6, equalTo(Optional.of(int.class)));
148+
}
149+
150+
@Test
151+
void shouldNotCastAsSubclassWhenNotPossible() {
152+
// given / when / then
153+
assertThat(ClassUtils.asSubclassIfPossible(String.class, Number.class), equalTo(Optional.empty()));
154+
assertThat(ClassUtils.asSubclassIfPossible(Number.class, Integer.class), equalTo(Optional.empty()));
155+
assertThat(ClassUtils.asSubclassIfPossible(Integer[].class, CharSequence[].class), equalTo(Optional.empty()));
156+
157+
assertThat(ClassUtils.asSubclassIfPossible(int.class, Integer.class), equalTo(Optional.empty()));
158+
assertThat(ClassUtils.asSubclassIfPossible(Integer.class, int.class), equalTo(Optional.empty()));
159+
}
129160
}
130161

131162
@Test

0 commit comments

Comments
 (0)