I have a method which essentially handles casting for config types, however upon specifying a generic type (such as List
), it becomes a problem of how to handle the specific type. In an ideal world, something such as using a type witness:
List<String> someVal = MyConfig.SOME_VAL.<List<String>>.as(List.class);'
(The full as
code):
/**
* Attempts to return the {@link Config} value as a casted type. If the
* value cannot be casted it will attempt to return the default value. If
* the default value is inappropriate for the class, the method will
* throw a {@link ClassCastException}.
*
* @since 0.1.0
* @version 0.1.0
*
* @param <T> The type of the casting class
* @param c The class type to cast to
* @return A casted value, or {@code null} if unable to cast. If the passed
* class parameter is of a primitive type or autoboxed primitive,
* then a casted value of -1 is returned, or {@code false} for
* booleans. If the passed class parameter is for {@link String},
* then {@link Object#toString()} is called on the value instead
*/
default public <T> T as(Class<T> c) {
Validate.notNull(c, "Cannot cast to null");
Validate.isTrue(Primitives.unwrap(c) != void.class, "Cannot cast to a void type");
Object o = this.get();
if (o == null) {
T back = Reflections.defaultPrimitiveValue(c);
if (back != null) { //catch for non-primitive classes
return back;
}
}
if (c == String.class) {
return (T) String.valueOf(o);
}
if (c.isInstance(o)) {
return c.cast(o);
}
if (c.isInstance(this.getDefault())) {
return c.cast(this.getDefault());
}
throw new ClassCastException("Unable to cast config value");
}
So essentially that leaves me with a two-part question: Why can't type witnesses be used for generics on a class (such as List(raw)
-> List<String>
), and how can I go about supporting retrieving a class with generic bounding without doing extraneous casting? The first point particularly baffles me, since this is perfectly legal:
List<String> test = new ArrayList<>();
test = MyConfig.FRIENDLY_MOBS.as(test.getClass());
Despite it returning a raw-typed list