-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed as not planned
Closed as not planned
Feature
Copy link
Description
Final hour concern - before 6.0.0 is GA!
I'm surprised to see these new method signatures on ExtensionContext.Store ...
<K, V> Object computeIfAbsent(K key,
Function<? super K, ? extends V> defaultCreator);
<K, V> V computeIfAbsent(K key,
Function<? super K, ? extends V> defaultCreator,
Class<V> requiredType);
... because imho it would be sufficient with just this one ...
<K, V> V computeIfAbsent(K key, Function<? super K, ? extends V> defaultCreator);
... having V
as return-type.
Current javadoc also pushes for the third parameter Class<V> requiredType
as a mean for better type safety:
* <p>For greater type safety, consider using
* {@link #computeIfAbsent(Object, Function, Class)} instead.
However, I dont agree, in part because this third method-parameter of type Class<V>
is not much help when considering generic type-parameters (e.g. collection types). - This example addresses it:
static class Config {
static List<Config> parse(String value) {return List.of();}
static List<Config> resolve(Method m) {
return parse(m.getAnnotation(ConfigData.class).value());
}
}
@Retention(RetentionPolicy.RUNTIME) @interface ConfigData { String value(); }
ExtensionContext.Store myStore;
/** alternative hack with proposed return-type V: */
<K,V> V computeIfAbsent(K key, Function<? super K, ? extends V> defaulter) {
return (V) myStore.computeIfAbsent(key, defaulter, Object.class);
}
List<Config> withReturnType_V_thisCompilesWithoutCast__(ExtensionContext ctx) {
return computeIfAbsent( ctx.getRequiredTestMethod(), Config::resolve);
}
List<StringBuilder> __andPreventsThisFromCompiling_asIntended__(ExtensionContext ctx) {
return computeIfAbsent( ctx.getRequiredTestMethod(), Config::resolve);
}
List<StringBuilder> __but_core_Store_method_allowsThisToCompile/*!!!*/(ExtensionContext ctx) {
/* ... i.e. the "requiredType" parameter does not enforce the desired type safety! */
return myStore.computeIfAbsent( ctx.getRequiredTestMethod(), Config::resolve, List.class);
/* Do note how this compiles - and also
* generic type-parameter erasure can make it survive quite far downstream during runtime. */
}
Summary
I see poor type safety with the computeIfAbsent(...)
methods signatures of version 6.0.0-RC3
and instead I propose a single method having return-type V
...
<K, V> V computeIfAbsent(K key, Function<? super K, ? extends V> defaultCreator);
... as a simplier and more type safe solution.