簡體   English   中英

是否可以從其構造函數的參數推斷出類的泛型類型參數?

[英]Can a class's generic type parameters be inferred from the arguments of its constructor?

這是我想做的:

我有一個接口服務,如下所示:

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

現在,我想鏈接兩個這樣的服務,同時保持其通用性:

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);
        }
    };
}

您不能有屬於您的類的泛型類型X (不是為每個方法調用重新選擇),也不屬於其聲明的一部分。

當然,您可以隱藏不安全的強制類型轉換,並確定您的程序可以運行,但是在Java類型系統的局限性中,這實際上是僅有的兩個選擇。

不過,我要做的是提供靜態工廠方法,而不是提供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被自動推斷且永不逃逸。

這將起作用:

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));
    }
}

為了獲得更好的協方​​差,您可以像這樣調整以上答案:

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));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM