[英]Generics, type erasure and static fabric method
例如,我有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();
}
}
現在我想使用這個回調讓get cats異步:
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))
顯然,擦除泛型類型變量的策略隨上下文而變化。 當然必須有規則如何運作,但我不知道他們,對不起。
從實際的角度來看,Jesper提出的解決方案,即在成功方法中提供類型信息似乎完全可以接受。
.success((List<Cat> cats) -> cats.forEach(Cat::meow))
否則,可以在一個方法中傳遞兩個Listeners:
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")
);
簡而言之,沒有。 從這個關於菱形運算符如何在Java 1.8中起作用的答案 ,任何鏈式方法調用都存在類型推斷問題。 你的例子很相似,因為
SimpleCallback<List<Cat>> callback = SimpleCallback
.success(cats -> cats.forEach(Cat::meow));
從success
的論證中推斷出C
型。
因此,您的選擇是:
對於您的示例,我更願意使用以下范例:
公共類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"));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.