先日、使用中に不都合がjava.util.ServiceLoader
あり、いくつかの質問がありました。
一般的なサービスがあるとします。
public interface Service<T> { ... }
特定のジェネリック型を持つ実装のみServiceLoader
をロードするように明示的に指示することはできませんでした。
ServiceLoader<Service<String>> services =
ServiceLoader.load(Service.class); // Fail.
私の質問はServiceLoader
、一般的なサービスの実装を安全にロードするために使用する合理的な方法は何ですか?
上記の質問をした後、Paŭlo の回答の前に、解決策を思いつくことができました。
public interface Service<T> { ...
// true if an implementation can handle the given `t' type; false otherwise.
public boolean canHandle(Class<?> t) { ...
public final class StringService implements Service<String> { ...
@Override public boolean canHandle(Class<?> t) {
if (String.class.isAssignableFrom(type))
return true;
return false;
}
public final class DoubleService implements Service<Double> { ...
// ...
public final class Services { ...
public static <T> Service<T> getService(Class<?> t) {
for (Service<T> s : ServiceLoader.load(Service.class))
if (s.canServe(t))
return s;
throw new UnsupportedOperationException("No servings today my son!");
}
同じ方法での変更boolean canServe(Class<?> t)
とboolean canServe(Object o)
変更は、より動的になる可能性があります(最初にインターフェイスに<T> Service<T> getService(Class<?> t)
メソッドがあったため、後者を自分で使用しています)。boolean canHandle(T t)