2

これが私がやりたいことです:

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

public interface Service<A extends Object, R extends Object> {
    R run(A a);
}

ここで、一般的なものを維持しながら、このような2つのサービスをリンクしたいと思います。

public class Link<A, R> implements Service<A, R> {

    private Service<A, X> s1; // fail
    private Service<X, R> s2; // fail

    public <X> Link(Service<A, X> s1, Service<X, R> s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    @Override
    public R run(A a) {
        return s2.run(s1.run(a));
    }
}

私が対処したい問題は、ジェネリック型XをクラスLinkに割り当てることですが、クラス宣言ではなく、コンストラクターを介して推測されるようにしたいのです。

それはどのように達成可能ですか?

編集:

私がこれを解決した方法は、リンクプロセスを実行するユーティリティ静的メソッドによるものです。

public static <A, I, R> Service<A, R> link(final Service<A, I> s1, final Service<I, R> s2) {
    return new Service<A, R>() {
        @Override
        public R run(A a) throws Exception {
            I intermediate = s1.run(a);
            return s2.run(intermediate);
        }
    };
}
4

3 に答える 3

4

Xクラスの一部である(メソッド呼び出しごとに新しく選択されていない)ジェネリック型を、その宣言の一部ではないようにすることはできません。

確かに、安全でないキャストを非表示にして、プログラムが機能することを確認することはできますが、Javaの型システムの制限における2つの選択肢はこれらだけです。

ただし、コンストラクターを提供する代わりにLink、静的ファクトリメソッドを提供します。

public static <A, X, R> Service<A, R> link(Service<A, X> s1, Service<X, R> s2) {
  return new Link<A, X, R>(s1, s2);
}

X...それが自動的に推測され、決して逃げないことを保証します。

于 2012-12-14T17:19:27.087 に答える
1

より良い共分散のために、あなたはこのように上記の答えを調整することができます:

public class Link <F, X, T>  implements Service <F, T> {
    private final Service<F, ? extends X> from;
    private final Service <X, ? extends T> to;

    public Link(Service <F, ? extends X> from, Service <X, ? extends T> to) {
        this.from = from;
        this.to = to;
    }

    @Override
    public T run (F input) {
        return to.run (from.run (input));
    }
}
于 2012-12-14T20:06:17.387 に答える
0

これは機能します:

public class Link<A, R, X> implements Service<A, R> {

    private Service<A, X> s1; 
    private Service<X, R> s2; 

    public Link(Service<A, X> s1, Service<X, R> s2) {
        this.s1 = s1;
        this.s2 = s2;
    }

    @Override
    public R run(A a) {
       return s2.run(s1.run(a));
    }
}
于 2012-12-14T17:39:36.273 に答える