通用铸造在Kotlin

我有以下的类和接口:

public interface ActivityComponent<T extends Activity> { void inject(T activity); } public interface MyActivityComponent extends ActivityComponent<MyActivity> { } public abstract class DaggerActivity extends Activity { abstract ActivityComponent getComponent(Context context); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityComponent component = getComponent(this); } } public class MyActivity extends DaggerActivity { @Override ActivityComponent getComponent(Context context) { MyActivityComponent component = buildComponent(); return component; } 

而这个类似(我认为?)Kotlin代码:

 public trait ActivityComponent<T : Activity> { public fun inject(activity: T) } public abstract class DaggerActivity : Activity { protected abstract fun getComponent(context: Context): ActivityComponent<Activity> // Type required override fun onCreate(savedInstanceState: Bundle?) { var component = getComponent(this) } } public class MyActivity extends DaggerActivity { override fun getComponent(context: Context): ActivityComponent<Activity> { val component: MyActivityComponent = buildComponent() return component as ActivityComponent<Activity> } } 

注意:MyActivityComponent实现总是使用Java,所以Dagger可以处理它。

“问题”是Kotlin中的MyActivity.getComponent()需要对返回类型进行MyActivityComponent类型转换,即使MyActivityComponent子类ActivityComponent

我对Kotlin的泛型的理解是公认的弱,而且我很难从Java的泛型翻译出来。 有人可以解释为什么这个演员是必要的,或者最好是正确的实施,无需铸造?

我也尝试过这样的事情:

 protected abstract fun <E : Activity> getComponent(context: Context): ActivityComponent<E> 

 protected abstract fun <A: Activity, E : ActivityComponent<A> getComponent(context: Context): E 

同样的结果(需要铸造)。

不同的是,在Java中,您正在使用原始类型ActivityComponent作为getComponent()的返回类型。 原始类型是Java 5中引入的Java遗留机制,主要是为了与Java 4集合向后兼容。

Kotlin没有原始类型。 相反,你可以使用“星型投影”,即ActivityComponent<*> ,它与Java的ActivityComponent<?>类似,我推荐使用它来代替原始类型。

所以,解决方案将是:

 fun getComponent(context: Context): ActivityComponent<*>