Loading generic service implementations via java.util.ServiceLoader -


I stumbled over some inconvenience by using the java.util.ServiceLoader and the other day. The trench is made in me.

Suppose I have general service:

  Public Interface Service & lt; T & gt; {...}   

I can not explicitly tell the ServiceLoader to load the only implementation with a specific general type .

  Service Loader & lt; Service & lt; String & gt; & Gt; Services = ServiceLoader.load (Service.class); // Failure   

My question is: What are the proper ways to use ServiceLoader to safely load the implementation of normal service?


After asking the above questions and the answer to Paimalo, I have been able to come up with a solution.

  Public Interface Services & lt; T & gt; {... true} If an implementation can handle the given `t 'type; Incorrect Otherwise Public Boolean Cahndal (class   

change boolean canServe (class boolean canServe (object o) and Is also changing. & Lt; T & gt; & Lt; T & gt; Similar service (class and lieutenant; ??) can be more dynamic than that (I'm using myself later because I have a method boolean canHandle (T t ) was initially the interface.)

The problem here is that the service loader can access all the files Using a file that is listed, in a given class / interface, the file is named after the interface name. It was not expected to understand the type parameter in the file name, and it is not normally possible to undergo a class object as normal.

So, you can get here only by looking at any type of your generic services, and then inspecting the object of your class to see if it is service & lt; String & gt; There is a subtype of .

Something like this:

  Classroom test {public service & lt; String & gt; GetStringService () {// It is a little strange that we can not explicitly construct a // parametric type with the raw type and parameters, so here // we use this solution. For this, a dummy method or / var / variable may be required if this method has the second return type. Parameterized type word string string string type = (Parametry type) Test.class.getMethod ("GetStringService"). GetGenericReturnType (); ServiceLoader & LT; & Lt ;? & Gt; & Gt; Loader = ServiceLoader.load (Service & lt;? & Gt; .class); (Service & lt ;? & gt; service: loader) {if (applicable (service.getClass (), stringServiceType) {@SuppressWarnings ("uncheck") service & lt; String & gt; S = (service) service; Return s; }}} Is using public boolean (class ?; & Gt; candidate, parametricized type} {for (type iFace: candidate.getGenericInterfaces ()) {if (iFace.equals (t)) {return true; } If (paragetized type iFace example of (parametricized type) iFace). Getra type (.) Equal (t. jrvat type ())) {return false; } } return false; }}   

It has not been tested, and interfaces enhanced by the interfaces of our class directly and the interfaces implemented by our (normal) superclasses should also be increased.

And of course, it only

  serve the example of a class device & lt; String & gt; {...}   

nothing like

  class examples & lt; X & gt; Service & lt; X & gt; {...}   

Where example & lt; String & gt; There may be a valid implementation of your service.

Comments