【问题标题】:Incorrect type detection in lambda with generic具有泛型的 lambda 中的类型检测不正确
【发布时间】:2017-10-26 11:03:21
【问题描述】:

我遇到了奇怪的问题。我有三个简化的演示类:

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()方法调用中的问题。

使用匿名类就可以了:

但是 lambda 错误类型是 Object:

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

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

在带有retrolambda 的Android Studio 2.3.3 和没有retrolambda 的Android Studio 3.0 中相同。

Sample project

【问题讨论】:

  • 尝试更改 lambda 的开头以指定类型,而不是强制转换: (QueryError e) -> // 代码 ...
  • 我已经试过了,没有帮助
  • 如果您让 onSuccess 返回 Query&lt;T&gt; 而不是 Query 可能会有所帮助。
  • 是的。它有助于。谢谢!

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


【解决方案1】:

您正在对onSuccess 方法的结果调用onError,而onSuccess 返回一个Query。当您在原始类型上调用方法时,所有类型参数都将被删除,并且所有泛型参数都将替换为其原始类型。因此,您的 lambda 被推断为 Clicker,实际上是 Clicker&lt;Object&gt;.

更改onSuccessonError 的签名以返回Query&lt;T&gt;,您的Clicker&lt;T&gt; 应该可以正确推断。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    相关资源
    最近更新 更多