java - Avoiding methods returning Wildcard types -
here's application design i'm trying avoid returning wildcard types method can invoke methods on returned object. suggestions? poor idea have static utility method find , return right handler implementation below after all?
the problem: have bunch of requests (and responses corresponding them). these requests have handled , results of handling (the responses) may used further processing. request handled @ given moment depends on few criteria (this enum
).
my approach: solution build several handlers, 1 each of request-response type combos , having them implement common interface method handle request.
here's how goes:
a family of handler classes implementing handler
interface:
interface handler<q extends request, r extends response> { r handlerequest(q); }
and static utility method companion class find right handler matching given criteria:
class handlers { handler<? extends request, ? extends response> handlerforcriteria(criteria criteria) { switch (criteria): ... // since there several handler implementations, couldn't avoid wildcard // types request , response } }
here's need use it:
handler<? extends request, ? extends response> matchinghandler = handlers.handlerforcriteria(criteria); myresponse response = matchinghandler.handlerequest(myrequest);
i'd able call handlerequest
above, i'm not allowed since matchinghandler
contains wildcard types (it can't tell if unknown wildcard type of request same type `myrequest).
use typed method cast if necessary:
class handlers { <r extends request, t extends response> handler<r, t> handlerforcriteria(criteria criteria) { handler<?, ?> handler = somestrategrythatisuntyped(); return (handler<r, t>)handler; // cast } }
so, why/when cast "safe"?
sometimes case both needed , safe. example, consider code:
private map<class<?>, handler<?>> handlers = new hashmap<>();
and populate in way guarantees type of class equals type of handler (which can't done in map's declaration):
public <t> void register(class<t> clazz, handler<t> handler) { handlers.put(clazz, handler); }
but method finds handler can't compiled safely based on map's definition:
public <t> handler<t> findhandler(class<t> clazz) { handler<?> handler = handlers.get(clazz); // although compiler can't assert it, handler of type t // cast safe, because programmatically constrain map's entries return (handler<t>)handler; // safe }
Comments
Post a Comment