Ghép nối Nhà cung cấp với một FunctionalInterface. Dưới đây là một số mã mẫu tôi đặt cùng nhau để chứng minh "ràng buộc" một tham chiếu hàm tạo cho một hàm tạo cụ thể với Hàm và các cách khác nhau để định nghĩa và gọi tham chiếu hàm dựng "nhà máy".
import java.io.Serializable;
import java.util.Date;
import org.junit.Test;
public class FunctionalInterfaceConstructor {
@Test
public void testVarFactory() throws Exception {
DateVar dateVar = makeVar("D", "Date", DateVar::new);
dateVar.setValue(new Date());
System.out.println(dateVar);
DateVar dateTypedVar = makeTypedVar("D", "Date", new Date(), DateVar::new);
System.out.println(dateTypedVar);
TypedVarFactory<Date, DateVar> dateTypedFactory = DateVar::new;
System.out.println(dateTypedFactory.apply("D", "Date", new Date()));
BooleanVar booleanVar = makeVar("B", "Boolean", BooleanVar::new);
booleanVar.setValue(true);
System.out.println(booleanVar);
BooleanVar booleanTypedVar = makeTypedVar("B", "Boolean", true, BooleanVar::new);
System.out.println(booleanTypedVar);
TypedVarFactory<Boolean, BooleanVar> booleanTypedFactory = BooleanVar::new;
System.out.println(booleanTypedFactory.apply("B", "Boolean", true));
}
private <V extends Var<T>, T extends Serializable> V makeVar(final String name, final String displayName,
final VarFactory<V> varFactory) {
V var = varFactory.apply(name, displayName);
return var;
}
private <V extends Var<T>, T extends Serializable> V makeTypedVar(final String name, final String displayName, final T value,
final TypedVarFactory<T, V> varFactory) {
V var = varFactory.apply(name, displayName, value);
return var;
}
@FunctionalInterface
static interface VarFactory<R> {
// Don't need type variables for name and displayName because they are always String
R apply(String name, String displayName);
}
@FunctionalInterface
static interface TypedVarFactory<T extends Serializable, R extends Var<T>> {
R apply(String name, String displayName, T value);
}
static class Var<T extends Serializable> {
private String name;
private String displayName;
private T value;
public Var(final String name, final String displayName) {
this.name = name;
this.displayName = displayName;
}
public Var(final String name, final String displayName, final T value) {
this(name, displayName);
this.value = value;
}
public void setValue(final T value) {
this.value = value;
}
@Override
public String toString() {
return String.format("%s[name=%s, displayName=%s, value=%s]", getClass().getSimpleName(), this.name, this.displayName,
this.value);
}
}
static class DateVar extends Var<Date> {
public DateVar(final String name, final String displayName) {
super(name, displayName);
}
public DateVar(final String name, final String displayName, final Date value) {
super(name, displayName, value);
}
}
static class BooleanVar extends Var<Boolean> {
public BooleanVar(final String name, final String displayName) {
super(name, displayName);
}
public BooleanVar(final String name, final String displayName, final Boolean value) {
super(name, displayName, value);
}
}
}
Trình biên dịch có thể đoán rằng đối số được cho là "xin chào"? – assylias
đó là câu hỏi của tôi, tôi muốn biết nếu nó có thể để cho các nhà cung cấp biết bằng cách nào đó rằng "hello" là một đối số cho các nhà xây dựng. Cố gắng làm điều này có thể là một thực hành không tốt trong lập trình hàm và tôi có thể sai khi nghĩ về nó, nhưng biết tại sao không làm điều đó không xứng đáng với một câu trả lời là – cahen
Câu hỏi của bạn đơn giản là không có ý nghĩa. Bạn viết “Tại sao các nhà cung cấp chỉ làm việc với các nhà xây dựng không có arg?”, Sau đó bạn tự chứng minh rằng một 'Nhà cung cấp' * làm việc với các đối số được cung cấp, tức là khi sử dụng một biểu thức lambda. Vì vậy, có vẻ như câu hỏi thực tế của bạn là "tại sao phương pháp tham chiếu chỉ hoạt động nếu các tham số chức năng khớp với thông số đích" và câu trả lời là vì đó là phương pháp tham chiếu phương pháp. Nếu danh sách tham số không khớp, hãy sử dụng biểu thức lambda như bạn đã hiển thị trong câu hỏi của mình. Bởi vì đó là biểu thức lambda dành cho (không độc quyền)… – Holger