【问题标题】:Kotlin equivalent for Java `? extends`Kotlin 等价于 Java `?扩展`
【发布时间】:2020-08-20 05:51:33
【问题描述】:

我正在尝试将模块类(dagger)转换为 kotlin 文件,但在尝试构建 kotlin 转换代码时遇到此问题。

@Binds 方法的参数类型必须可分配给返回类型

这就是我遇到问题的地方。

@Binds
@IntoMap
@ClassKey(EnterEmailFragment::class)
abstract fun bindsEnterEmailInjector(injector: EnterEmailInjector): ScreenInjector<in Fragment, out Any>

Java 代码:(Java 代码运行良好!)

@Binds
@IntoMap
@ClassKey(EnterEmailFragment.class)
abstract ScreenInjector<? extends Fragment, ? extends Object> bindsEnterEmailInjector(EnterEmailInjector injector);

这就是 .class 文件的样子

public abstract class com.gojek.driver.ulysses.email.di.EmailScreenFactoryModule {
  public static final com.gojek.driver.ulysses.email.di.EmailScreenFactoryModule$Companion Companion;

  public abstract com.gojek.driver.base.ScreenInjector<androidx.fragment.app.Fragment, java.lang.Object> bindsEnterEmailInjector(com.gojek.driver.ulysses.email.di.EnterEmailInjector);

  public com.gojek.driver.ulysses.email.di.EmailScreenFactoryModule();
    Code:
       0: aload_0
       1: invokespecial #16                 // Method java/lang/Object."<init>":()V
       4: return

  static {};
    Code:
       0: new           #42                 // class com/gojek/driver/ulysses/email/di/EmailScreenFactoryModule$Companion
       3: dup
       4: aconst_null
       5: invokespecial #49                 // Method com/gojek/driver/ulysses/email/di/EmailScreenFactoryModule$Companion."<init>":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
       8: putstatic     #40                 // Field Companion:Lcom/gojek/driver/ulysses/email/di/EmailScreenFactoryModule$Companion;
      11: return

  public static final com.gojek.driver.ulysses.email.di.EnterEmailInjector providesEnterEmailInjector(com.gojek.driver.ulysses.driver.DriverProfileUsecase);
    Code:
       0: getstatic     #40                 // Field Companion:Lcom/gojek/driver/ulysses/email/di/EmailScreenFactoryModule$Companion;
       3: aload_0
       4: invokevirtual #44                 // Method com/gojek/driver/ulysses/email/di/EmailScreenFactoryModule$Companion.providesEnterEmailInjector:(Lcom/gojek/driver/ulysses/driver/DriverProfileUsecase;)Lcom/gojek/driver/ulysses/email/di/EnterEmailInjector;
       7: areturn
}

不太确定我在这里缺少什么。

【问题讨论】:

  • 协方差 ? extends 在 Kotlin 中是 out。在 Kotlin 中,逆变 ? superin。看看Understanding Generics in Kotlin/Java
  • Kotlin 具有协变和逆变,就像 @AnimeshSahu 所说的那样。您能否详细说明您所面临的完整代码问题。
  • 在 Java 中,两个类型参数都是 ? extends,在 Kotlin 中,一个是 in,一个是 out。两者都应该是out
  • @AnimeshSahu @alokHarman 我什至在这两种情况下都尝试过out,但匕首仍然在抛出这个问题@Binds methods' parameter type must be assignable to the return type

标签: java android kotlin dagger-2


【解决方案1】:

它实际上是一个已知问题,发生在 Kotlin 的投影类型上。匕首的github issue报道。

作为解决该问题的一种变通方法,github 问题和this 文章建议使用@JvmSuppressWildcards 来抑制编译器创建的警告。

@Binds
@IntoMap
@ClassKey(EnterEmailFragment::class)
abstract fun bindsEnterEmailInjector(injector: EnterEmailInjector)
    : ScreenInjector<out @JvmSuppressWildcards Fragment, out @JvmSuppressWildcards Any>

【讨论】:

  • 这对我也不起作用。遇到同样的问题
  • @PrithviBhola 您现在收到什么错误消息?是一样的吗?
  • 是的@animesh-sahu
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多