通用

时间:2017-10-26 11:03:21

标签: java android-studio generics lambda java-8

我面临着奇怪的问题。我有三个简化的演示类:

public interface Clicker<T> {
   void onClick(T obj);
}

public final class QueryError {

   private String type, message;

   public QueryError(String type, String message) {
       this.type = type;
       this.message = message;
   }

   public String getType() {
       return type;
   }
   public String getMessage() {
       return message;
   }
}

public final class Query<T> extends AsyncTask<Void, Void, String> {

   private Clicker<T> onSuccessListener;
   private Clicker<QueryError> onErrorListener;

   public Query onSuccess(Clicker<T> onSuccessListener) {
       this.onSuccessListener = onSuccessListener;
       return this;
   }

   public Query onError(Clicker<QueryError> onErrorListener) {
       this.onErrorListener = onErrorListener;
       return this;
   }

   public void call() {
       execute();
   }

   @Override
   protected String doInBackground(Void... params) {
       return "done";
   }
}

onError()方法调用中的问题。

使用匿名课程就可以了:

enter image description here

但是lambda错误类型是Object:

enter image description here enter image description here enter image description here

只有输入类型可以提供帮助,但它非常不舒服:

enter image description here

为什么lambda的onSuccess()类型是正确的(在类泛型中定义),而onError()中的类型是Object而不是QueryError?也许我做错了什么?

在带有retrolambda的Android Studio 2.3.3和没有retrolambda的Android Studio 3.0中也是如此。

Sample project

1 个答案:

答案 0 :(得分:4)

您正在onError方法的结果上调用onSuccess,而onSuccess会返回Query。在原始类型上调用方法时,将擦除所有类型参数,并将任何泛型参数替换为其原始类型。因此,您的lambda被推断为Clicker,实际上是Clicker<Object>.

更改onSuccessonError的签名以返回Query<T>,并且应正确推断您的Clicker<T>