Общее литье в Котлине

У меня есть следующие классы и интерфейсы:

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; } 

И это аналогичное (я думаю?) Код Котлина:

 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, так что Кинжал может ее обработать.

«Проблема» в том, что MyActivity.getComponent () в Kotlin требует отбрасывания возвращаемого типа, хотя MyActivityComponent подклассифицирует ActivityComponent .

Мое понимание дженериков Котлина, по общему признанию, слабое, и у меня проблемы с переходом от дженериков 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, представленный на Java 5, в основном для обратной совместимости с коллекциями Java 4.

У Котлина нет сырых типов. Вместо этого вы можете использовать «звездную проекцию», то есть ActivityComponent<*> , которая смутно аналогична ActivityComponent<?> Java ActivityComponent<?> , Которую я бы рекомендовал использовать вместо необработанного типа.

Таким образом, решение будет:

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