Я использую несколько интерфейсов с универсальными типами. При объединении их вместе у меня возникают некоторые проблемы, когда мне приходится использовать их из части кода, которая не знает о конкретном типе универсального параметра.
Предположим, у меня есть следующий интерфейс:
public interface MyObjectInterface<T extends Number> {}
Объект, реализующий этот интерфейс, хранится в универсальной коллекции того же универсального типа:
public interface MyCollectioninterface<T extends Number> {
public void updateObject(MyObjectInterface<T> o);
}
Конкретные экземпляры MyCollectionInterface содержат несколько MyObjectInterface одного и того же универсального параметра:
public class ConcreteCollection<T extends Number> implements
MyCollectionInterface<T> {
List<MyObjectInterface<T>> list;
public void updateObject(MyObjectInterface<T> o){}
}
Теперь у меня есть несколько вопросов о том, как использовать эти универсальные интерфейсы из клиентского класса, который (и должен быть) не знает о конкретном типе дженериков.
Предположим, у меня есть следующий класс:
public class ClientClass{
private MyCollectionInterface<?> collection; //1st possibility
private MyCollectionInterface collection; //2nd possibility
public ClientClass(MyCollectionInterface<?> collection){
this.collection = collection;
}
public void foo(MyObjectInterface<?> o){
this.collection.updateObject(o); //this doesn't compile
}
public void foo(MyObjectInterface<? extends Number> o){
this.collection.updateObject(o); //this doesn't compile either
}
public void bar(MyObjectInterface o){
MyObject b = o; //warning
this.collection.updateObject(o); //this compile but with warnings
}
}
Первый вопрос:
- Учитывая тот факт, что ClientClass не заботится о том, какой конкретный тип, расширяющий Number, является коллекцией, должен ли я объявить коллекцию с символом "?" или без него? ? Если я использую вторую версию, я получаю следующее предупреждение:
MyCollectionInterface — это необработанный тип. Ссылки на универсальный тип LatticeInterface должны быть параметризованы.
Второй вопрос:
- Почему метод foo не компилируется?
Третий вопрос:
- Кажется, мне нужно использовать сигнатуру бара для вызова метода updateObject. В любом случае это решение выдает предупреждение при попытке назначить параметр MyObjectInterface, как в первом вопросе. Могу ли я удалить это предупреждение?
Последние вопросы:
- Я делаю что-то странное с этими универсальными интерфейсами, и я должен реорганизовать свой код?
- Мне действительно нужно заботиться обо всех этих предупреждениях?
- Как я могу использовать безопасный общий интерфейс из класса, где я не знаю его конкретного типа?
MyObjectInterface
вместоMyObject
в методахfoo
иbar
? - person guardianpt   schedule 04.09.2011