例如,我有SimpleCallback类
public class SimpleCallback<T> implements Callback<T> {
private SuccessListener<T> successListener;
private ErrorListener errorListener;
protected SimpleCallback() {
}
public static <C> SimpleCallback<C> success(SuccessListener<C> listener) {
SimpleCallback<C> callback = new SimpleCallback<>();
callback.successListener = listener;
return callback;
}
public SimpleCallback<T> error(ErrorListener errorListener) {
this.errorListener = errorListener;
return this;
}
@Override
public void onComplete(T result) {
notifySuccess(result);
}
@Override
public void onError() {
notifyError();
}
public interface SuccessListener<T> {
void onSuccess(T result);
}
public interface ErrorListener {
void onError();
}
}
现在我想使用这个回调来让猫异步:
SimpleCallback<List<Cat>> callback = SimpleCallback
.success(cats -> cats.forEach(Cat::meow));
现在没关系,但是当我想添加错误监听器时,我的猫会成为原始对象
SimpleCallback<List<Cat>> callback = SimpleCallback
.success(cats -> cats.forEach(Cat::meow)) <-- Here cats become objects
.error(() -> System.out.println("Cats error"));
其中一个解决方案使用显式泛型类型:
SimpleCallback<List<Cat>> callback = SimpleCallback.<List<Cat>>
.success(cats -> cats.forEach(Cat::meow))
.error(() -> System.out.println("Cats error"));
但它看起来有点难看。那么在没有显式泛型类型的情况下创建回调的方法是什么?
UPD:我认为@Jesper提供了很好的解决方案
另一种解决方案是明确提供lambda表达式的参数类型:
.success((List<Cat> cats) -> cats.forEach(Cat::meow))
答案 0 :(得分:0)
显然,擦除泛型类型变量的策略随上下文而变化。 当然必须有规则如何运作,但我不知道,对不起。
从实际的角度来看,Jesper建议的解决方案,即在成功方法中提供类型信息似乎完全可以接受。
.success((List<Cat> cats) -> cats.forEach(Cat::meow))
否则,可以通过一种方法传递两个Listener:
public static <C> SimpleCallback<C> create(
SuccessListener<C> successListener, ErrorListener errorListener) {
SimpleCallback<C> callback = new SimpleCallback<>();
callback.successListener = successListener;
callback.errorListener = errorListener;
return callback;
}
并一步创建回调:
Callback<List<Cat>> callback = SimpleCallback
.create(
cats -> cats.forEach(Cat::meow),
() -> System.out.println("Cats error")
);
答案 1 :(得分:0)
简而言之,没有。从this answer about how the diamond operator functions in Java 1.8开始,任何链式方法调用都存在类型推断问题。你的例子很相似,因为
SimpleCallback<List<Cat>> callback = SimpleCallback
.success(cats -> cats.forEach(Cat::meow));
从C
的参数中推断出类型success
。
因此您的选择是:
对于您的示例,我更倾向于使用以下范例:
public class SimpleCallback实现了Callback {
private SuccessListener<T> successListener;
private ErrorListener errorListener;
protected SimpleCallback() {
}
public static <C> SimpleCallback<C> create() {
return new SimpleCallback<>();
}
public SimpleCallback<T> withSuccessListener(SuccessListener<T> listener) {
this.successListener = listener;
return this;
}
public SimpleCallback<T> withErrorListener(ErrorListener errorListener) {
this.errorListener = errorListener;
return this;
}
@Override
public void onComplete(T result) {
notifySuccess(result);
}
@Override
public void onError() {
notifyError();
}
public interface SuccessListener<T> {
void onSuccess(T result);
}
public interface ErrorListener {
void onError();
}
}
然后在一行中创建,添加并链接到下一行。
SimpleCallback<List<Cat>> callback = SimpleCallback.create();
callback = callback.success(cats -> cats.forEach(Cat::meow))
.error(() -> System.out.println("Cats error"));