I am trying to validate a result from a library (Panache / Hibernate using Quarkus) by passing the object to a "validator", where the validator validates that the result is not empty and subsequently returns the passed object back to the caller.
In this example, listAll()
is from PanacheEntityBase
and simply returns a list of Employee
objects. If this List
is empty, as in, there are no results in the result set, it does not throw an exception. So to avoid having an empty / null check in every call, I am writing the follow convenience class to validate all results.
In my validator:
public class ResultValidator {
public static <T> Collection<T> validate(Collection<T> result, Class<T> type) throws EmptyResultException {
if (result.isEmpty()) {
throw new EmptyResultException();
}
return result;
}
}
The caller would invoke this like:
return ResultValidator.validate(listAll(), Employee.class);
Rather, I'm having to upcast:
return (List<Employee>) ResultValidator.validate(listAll(), Employee.class);
The code above, that invokes validate
, results in a compiler error Cannot convert from Collection<> to List<>
. Unless I'm upcasting to List<>
or explicitly defining List<>
type in my validate
implementation, I will get this error.
What do I need to change in my validate(Collection, Class)
implementation to avoid upcasting or declaring an explicit type?
If your intent is to return 'self', then:
public static <T, C extends Collection<T>> C validate(C result, Class<T> type) {
// note that requiring a `Class<T>` is a code smell...
if (result.isEmpty()) throw new EmptyResultException();
return result;
}
List<String> list = ...;
list = validate(list, String.class);
now works fine, but note that it is not possible to make a new C
instance. You're either returning result
straight up, and therefore the fact that validate
returns at all is, at best, some code/API convenience but not inherently useful, or, you can't use this, and you'd need a 'make a new collection' factory. That would get you to:
public static <T, C extends Collection<T>> C validate(C result, Class<T> type, Supplier<C> collectionMaker) {
...
}
Where the caller would have to provide something. e.g.:
List<String> list = ...;
validate(list, String.class, () -> new ArrayList<String>());
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments