Kotlin 中的通用铸造
Generic casting in 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 可以处理它。
"problem" 是 Kotlin 中的 MyActivity.getComponent() 需要转换为 return 类型,即使 MyActivityComponent
sub类 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 中,您使用 raw 类型 ActivityComponent
作为 getComponent()
的 return 类型.原始类型是 Java 在 Java 5 中引入的遗留机制,主要是为了向后兼容 Java 4 集合。
Kotlin 没有原始类型。相反,您可以使用 "star-projection",即 ActivityComponent<*>
,它与 Java 的 ActivityComponent<?>
有点相似,无论如何我建议使用它而不是原始类型。
所以,解决方案是:
fun getComponent(context: Context): ActivityComponent<*>
我有以下 类 和接口:
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 可以处理它。
"problem" 是 Kotlin 中的 MyActivity.getComponent() 需要转换为 return 类型,即使 MyActivityComponent
sub类 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 中,您使用 raw 类型 ActivityComponent
作为 getComponent()
的 return 类型.原始类型是 Java 在 Java 5 中引入的遗留机制,主要是为了向后兼容 Java 4 集合。
Kotlin 没有原始类型。相反,您可以使用 "star-projection",即 ActivityComponent<*>
,它与 Java 的 ActivityComponent<?>
有点相似,无论如何我建议使用它而不是原始类型。
所以,解决方案是:
fun getComponent(context: Context): ActivityComponent<*>