4

私はこのようなインターフェースを持っています:

public interface BatchSynchronisedPool<R extends Runnable> {
    void execute(R runnable, Object batchIdentifier);
    public <T> Future<T> submit(Callable<T> callable, Object batchIdentifier);
}

Callableの上限を推測したいのですが、それでも<T>メソッドの引数を保持できるようにしたいです。

public interface BatchSynchronisedPool<R extends Runnable, C extends Callable> {
    void execute(R runnable, Object batchIdentifier);
    public <T> Future<T> submit(C<T> callable, Object batchIdentifier);
}

C私が指定するタイプは特定の範囲のT引数しかとらない可能性があるため、明らかにそれは機能しません。しかし、今あなたは私がやろうとしていることの一般的なことを知っています、可能な解決策はありますか、それとも私は常に呼び出し可能なものを提出しなければならないのですか?(または、ジェネリックを完全に削除して、安全でないキャストを実行します)

4

1 に答える 1

4

私は100%確信しているわけではありませんが、ここでやろうとしていることができるとは思いません。は汎用ではないためC、は使用できませんC<T>。以下のコードはたくさんありますが、tl;drはオプション3を取ります。最終的に実際に変わるのは、BatchSynchronisedPool作成する必要のあるオブジェクトの数だけです。これは、実際にはかなりのオーバーヘッドではありません...


1.<T>メソッドのジェネリック型パラメーターを保持し、を送信してCallable<T>、このインターフェイスを実装するクラスで、元のソリューションのように型のランタイムチェックを実行します。

public interface BatchSynchronisedPool<R extends Runnable> {
    void execute(R runnable, Object batchIdentifier);
    public <T> Future<T> submit(Callable<T> callable, Object batchIdentifier);
}

public class MyBSP<R, C> implements BatchSynchronisedPool<R, C> {
    void execute(R runnable, Object batchIdentifier) { ... }
    public <T> Future<T> submit(Callable<T> callable, Object batchIdentifier) {
        // Check types.
        if (!(callable instanceof MyDesiredCallableClass)) {
            throw new IllegalArgumentException("Types don't match.");
        }

        // Do work.
        T result = callable.call();

        ...
    }
}

public class MyUsageClass {
     public static void main(String[] args) {
         // Submit string.
         MyBSP<Runnable> bsp = new MyBSP<Runnable>();
         bsp.submit(new StringCallable(), someObject1);

         // Submit integer.
         bsp.submit(new IntegerCallable(), someObject2);
     }
}

2.<T>メソッドのジェネリック型パラメーターを保持し、を送信して、このインターフェイスを実装するクラスで、提案したようCにキャストを実行します。

public interface BatchSynchronisedPool<R extends Runnable, C extends Callable> {
    void execute(R runnable, Object batchIdentifier);
    public <T> Future<T> submit(Class<T> cls, C callable, Object batchIdentifier);
}

public class MyBSP<R, C> implements BatchSynchronisedPool<R, C> {
    void execute(R runnable, Object batchIdentifier) { ... }
    public <T> Future<T> submit(Class<T> cls, C callable, Object batchIdentifier) {
        // Do work... with a cast.
        T result = cls.cast(callable.call());

        ...
    }
}

public class MyUsageClass {
     public static void main(String[] args) {
         // Submit string.
         MyBSP<Runnable, Callable> bsp = new MyBSP<Runnable, Callable>();
         bsp.submit(new StringCallable(), someObject1);

         // Submit integer.
         bsp.submit(new IntegerCallable(), someObject2);
     }
}

3.BatchSynchronisedPoolTTクラスのジェネリック型パラメーターとして指定して、送信しようとしている型ごとに新しいものを作成します。次に、異なるタイプを呼び出すたびにsubmit、の新しいインスタンスを生成する必要がありますBatchSynchronisedPool

public interface BatchSynchronisedPool<T, R extends Runnable, C extends Callable<T>> {
    void execute(R runnable, Object batchIdentifier);
    public Future<T> submit(C callable, Object batchIdentifier);
}

public class MyBSP<T, R, C> implements BatchSynchronisedPool<T, R, C> {
    void execute(R runnable, Object batchIdentifier) { ... }
    public Future<T> submit(C callable, Object batchIdentifier) {
        // Do work.  Types are okay; no checking or casting needed!
        T result = callable.call();

        ...
    }
}

public class MyUsageClass {
     public static void main(String[] args) {
         // Submit string.
         MyBSP<String, Runnable, Callable<String>> stringBsp = new MyBSP<String, Runnable, Callable<String>>();
         stringBsp.submit(new StringCallable(), someObject1);

         // Submit integer.
         MyBSP<Integer, Runnable, Callable<Integer>> integerBsp = new MyBSP<Integer, Runnable, Callable<Integer>>();
         integerBsp.submit(new IntegerCallable(), someObject2);
     }
}
于 2012-07-25T09:40:56.110 に答える