Ответ 1
Вы можете заставить параметры быть одного типа, выполнив следующие действия:
// the first class, A<K>:
class A<K> {
void f(K x) {}
}
// the second class, defining the method with generic type parameters
class Test {
<T> void foo(A<T> a, T x) {
a.f(x); // now it works!
}
}
// a third class, that uses the above two:
class Main {
public static void main(final String... args) {
final Test test = new Test();
final A<String> a = new A<>();
test.foo(a, "bar");
}
}
Что это такое: метод foo
определяет параметр типового типа T
и использует его для обеспечения того, чтобы параметр типа K
класса A
должен соответствовать типу x
, второй параметр foo
.
Вы можете даже наложить ограничения на <T>
, если хотите, и если это имеет смысл для вашей проблемы, например <T extends Bar> void foo(A<T> a, T x) {...}
или super
. Вы хотели бы этого, если, как сказал Джони в комментарии в вопросе, x
на самом деле является типом, а не параметром типа: вы должны использовать <T extends X> void foo(...)
.
После того, как вы указали больше кода, проблема становится ясной.
Метод .get()
контейнера возвращает экземпляр A<? extends K>
. Поэтому параметр типа экземпляра, который вы получаете из .get()
, не указан полностью. Как правило, это не очень хороший дизайн для возврата такого неуказанного типа. Для видео-презентации с Джошуа Блохом, автором Effective Java и многих API-интерфейсов и функций на Java, показывающих, как улучшить такой API, проверьте это: http://www.youtube.com/watch?v=V1vQf4qyMXg&feature=youtu.be&t=22m. В точности 25'36 ", Джошуа Блох говорит:" Не пытайтесь использовать их [подстановочные типы] для возвращаемых значений ", и он объясняет это позже. В принципе, вы не получаете больше гибкости, используя их, и просто делаете это очень тяжело для пользователей API, чтобы справиться с ним (вы просто почувствовали эффект от этого...).
Чтобы исправить ошибку, вы можете просто попытаться изменить подпись .get()
на A<K> get()
, поэтому класс контейнера будет выглядеть следующим образом:
public class Container<K> {
A<K> get() {
return new A<K>();
}
}
Поскольку вы знаете, что get()
возвращает экземпляр A<K>
, нет причин использовать старшую подпись: он просто заставляет вас потерять информацию, которую вы уже знаете!
И если это все еще не работает, ваша проблема может быть где-то в другом месте, и вам нужно будет показать еще больше кода... или еще лучше, задайте другие вопросы!:)