在Kotlin的通用铸造

时间:2015-02-18 18:14:54

标签: java generics 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子类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

结果相同(需要施法)。

1 个答案:

答案 0 :(得分:14)

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

Kotlin没有原始类型。相反,你可以使用&#34; star-projection&#34;,即ActivityComponent<*>,它与Java的ActivityComponent<?>模糊地类似,我建议使用它而不是原始的fun getComponent(context: Context): ActivityComponent<*> 无论如何都要输入。

所以,解决方案是:

{{1}}
相关问题