【发布时间】:2016-07-08 11:48:44
【问题描述】:
例如,我有 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))
【问题讨论】:
-
另一种解决方案是显式提供 lambda 表达式的参数类型:
.success((List<Cat> cats) -> cats.forEach(Cat::meow)) -
请说明问题所在。如果只是它看起来不熟悉,那么我会说:习惯它比使用带有所有缺点的原始类型要好得多......
-
@martinhh 问题是关于类型推断:为什么在调用
.success(...)之后添加.error(...)时,类型推断不再起作用(现在需要显式指定类型) . -
举个更简单的例子,
class Box<T> { T t; public Box<T> set(T t) { this.t = t; return this; } public T get() { return t;}}类显示了同样的问题。String s = new Box<String>().set("Hello").get();和Box<String> b = new Box<>(); String s = b.set("Hello").get();有效,但String s = new Box<>().set("Hello").get()无效。我认为这与<>如何解析为一种类型有关。也许这为寻找答案提供了方向?
标签: java generics type-erasure