Skip to content

Commit cd7adc1

Browse files
committed
Don't wrap constructor in Optional because it doesn't play well with wildcards
1 parent 3f63cec commit cd7adc1

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

src/main/java/ch/jalu/typeresolver/reflect/ConstructorUtils.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package ch.jalu.typeresolver.reflect;
22

3+
import org.jetbrains.annotations.Nullable;
4+
35
import java.lang.reflect.Constructor;
46
import java.util.Arrays;
5-
import java.util.Optional;
67
import java.util.stream.Collectors;
78

89
/**
@@ -14,18 +15,20 @@ private ConstructorUtils() {
1415
}
1516

1617
/**
17-
* Returns the specified constructor if it exists, otherwise returns an empty Optional.
18+
* Returns the specified constructor if it exists, otherwise null.
1819
*
1920
* @param clazz the class to search in
2021
* @param parameterTypes the parameter types the constructor must match
2122
* @param <T> class type
22-
* @return optional with the matching constructor, or empty optional
23+
* @return the matching constructor, or null
2324
*/
24-
public static <T> Optional<Constructor<T>> tryFindConstructor(Class<T> clazz, Class<?>... parameterTypes) {
25+
// Optional<Constructor<T>> would be a nicer return type, but generics don't play well when the incoming `clazz`
26+
// parameter is typed as Class<?>
27+
public static <T> @Nullable Constructor<T> getConstructorOrNull(Class<T> clazz, Class<?>... parameterTypes) {
2528
try {
26-
return Optional.of(clazz.getDeclaredConstructor(parameterTypes));
29+
return clazz.getDeclaredConstructor(parameterTypes);
2730
} catch (NoSuchMethodException ignore) {
28-
return Optional.empty();
31+
return null;
2932
}
3033
}
3134

src/test/java/ch/jalu/typeresolver/reflect/ConstructorUtilsTest.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
import java.lang.reflect.Constructor;
66
import java.util.ArrayList;
7-
import java.util.Optional;
87

98
import static org.hamcrest.MatcherAssert.assertThat;
109
import static org.hamcrest.Matchers.equalTo;
1110
import static org.hamcrest.Matchers.instanceOf;
1211
import static org.hamcrest.Matchers.notNullValue;
12+
import static org.hamcrest.Matchers.nullValue;
1313
import static org.junit.jupiter.api.Assertions.assertThrows;
1414

1515
/**
@@ -20,12 +20,24 @@ class ConstructorUtilsTest {
2020
@Test
2121
void shouldReturnConstructorIfApplicable() throws NoSuchMethodException {
2222
// given / when
23-
Optional<Constructor<Sample>> constr1 = ConstructorUtils.tryFindConstructor(Sample.class, int.class, String.class);
24-
Optional<Constructor<Sample>> constr2 = ConstructorUtils.tryFindConstructor(Sample.class, int.class, long.class);
23+
Constructor<Sample> constr1 = ConstructorUtils.getConstructorOrNull(Sample.class, int.class, String.class);
24+
Constructor<Sample> constr2 = ConstructorUtils.getConstructorOrNull(Sample.class, int.class, long.class);
2525

2626
// then
27-
assertThat(constr1, equalTo(Optional.of(Sample.class.getDeclaredConstructor(int.class, String.class))));
28-
assertThat(constr2, equalTo(Optional.empty()));
27+
assertThat(constr1, equalTo(Sample.class.getDeclaredConstructor(int.class, String.class)));
28+
assertThat(constr2, nullValue());
29+
}
30+
31+
@Test
32+
void shouldCompileWithWildcard() {
33+
// given
34+
Class<?> clazz = Sample.class;
35+
36+
// when
37+
Constructor<?> result = ConstructorUtils.getConstructorOrNull(clazz, String[].class);
38+
39+
// then
40+
assertThat(result, nullValue());
2941
}
3042

3143
@Test

0 commit comments

Comments
 (0)