Bạn có thể khai báo một phương pháp chung với một loại định nghĩa đệ quy
<G extends Function<G, IntUnaryOperator>> IntUnaryOperator g(G g) {
return g.apply(g);
}
gì không làm việc, là để gọi phương pháp này với một biểu thức lambda, gán biểu thức lambda để G
. The specification nói
15.27.3. Loại một biểu thức Lambda
Một biểu thức lambda là tương thích trong một bối cảnh chuyển nhượng, bối cảnh gọi, hoặc bối cảnh đúc với một loại mục tiêu T nếu T là một kiểu giao diện chức năng (§9.8) ...
và G
được không phải là giao diện chức năng, mà là tham số kiểu và không có cách nào để suy ra loại giao diện thực tế cho G
tại đây.
Đó vẫn hoạt động, khi bạn sử dụng giao diện thực tế G
cho biểu thức lambda:
IntUnaryOperator Y(Function<IntUnaryOperator, IntUnaryOperator> f) {
return g((G)g -> f.apply(x -> g.apply(g).applyAsInt(x)));
}
// renamed the type parameter from G to F to avoid confusion
<F extends Function<F, IntUnaryOperator>> IntUnaryOperator g(F f) {
return f.apply(f);
}
// can't get rid of this interface
interface G extends Function<G, IntUnaryOperator> {/**/}
hoặc
IntUnaryOperator fact = Y(rec -> n -> n == 0 ? 1 : n * rec.applyAsInt(n - 1));
IntUnaryOperator Y(Function<IntUnaryOperator, IntUnaryOperator> f) {
return this.<G>g(g -> f.apply(x -> g.apply(g).applyAsInt(x)));
}
// renamed the type parameter from G to F to avoid confusion
<F extends Function<F, IntUnaryOperator>> IntUnaryOperator g(F f) {
return f.apply(f);
}
// can't get rid of this interface
interface G extends Function<G, IntUnaryOperator> {/**/}
Vì vậy, các phương pháp g
là chung không có sự phụ thuộc vào giao diện G
, nhưng giao diện vẫn được yêu cầu để được sử dụng làm loại mục tiêu cho biểu thức lambda.
Tôi khá chắc chắn điều đó là không thể. Java không cung cấp một cách để yêu cầu một tham số chung nhất định là một giao diện chức năng AFAIK. – Ryan