2016-07-21 5 views
4

У меня есть универсальный класс MyClass<T> со статическим фабричным методом и присваивателя:Java дженериков: несовместимые типы

public class MyClass<T> { 
    public static <T> MyClass<T> with(Context context) { 
     MyClass<T> myClass = new MyClass<>(); 
     myClass.context = context; 
     return myClass; 
    } 
    public void setClass(Class<? extends CustomClass<T>> customClass) { 
     ... 
    } 
    ... 
} 

С методом сеттер, пользователь может установить любой класс, который наследуется от «CustomClass».

Пока все хорошо. Если да, то:

MyClass<String> myClass = MyClass.with(this); 
myClass.setClass(MyCustomClass.class); 

Он отлично работает. Но если я это сделаю:

MyClass.with(this).setClass(MyCustomClass.class); 

Он не скомпилирован! Выходы компилятора:

Error:(44, 87) error: incompatible types: Class<MyCustomClass> cannot be converted to Class<? extends MyCustomClass<Object>> 

Я не знаю, почему он не будет компилироваться со вторым вариантом. MyCustomClass, как:

public class MyCustomClass extends CustomClass<String> 

ответ

5

Пожалуйста, обратите внимание, что вы получили информацию о пропавших без вести между рабочим примером и вашего однострочником, который имеет ошибку компиляции.

Он не знает специализации. Вам нужно сделать что-то вроде

MyClass.<String>with(this).setClass(MyCustomClass.class); 

поэтому он знает, что вы будете «говорящими струнами».

+0

Спасибо вам большое! Работает! –

1

Во втором утверждении вы не определяете тип T, поэтому компилятор не может скомпилировать из-за ограничения на setClass.

следует добавить T в функции with для переменной цели:

public static <T> MyClass<T> with(Object context, Class<T> clazz) { 
    MyClass<T> myClass = new MyClass<>(); 
    myClass.context = context; 
    return myClass; 
    } 

MyClass.with(this, String.class).setClass(MyCustomClass.class); 

или передать:

MyClass.<String>with(this).setClass(MyCustomClass.class); 
+0

Спасибо вам большое! Это решение также работает! –

Смежные вопросы