Java. Подстановочные знаки в коллекцияхJava. Подстановочные знаки в коллекциях
У меня возникли проблемы с пониманием подстановочных знаков в коллекциях, даже после прочтения подобных сообщений в Stack Overflow и различных сайтах учебников. Ниже я привел очень простой пример. Можете ли вы объяснить, как я выбрал бы между Collection<myClass>
, Collection< ? Extends MyClass >
и Collection< ? Super MyClass >
?
package z5;
import java.util.ArrayList;
public class Z5 {
public static class Animal{
}
public static class Mammal extends Animal{
}
public static class Reptile extends Animal{
}
public static class Lion extends Mammal{
}
public static class Tiger extends Mammal{
}
public static class Snake extends Reptile{
}
public static void main(String[] args) {
ArrayList<Mammal> catHouse1 = new ArrayList<Mammal>();
catHouse1.add(new Lion());
catHouse1.add(new Tiger());
catHouse1.add(new Mammal());
catHouse1.add(new Animal()); //ERROR
ArrayList<? super Mammal> catHouse2 = new ArrayList<Mammal>();
catHouse2.add(new Lion());
catHouse2.add(new Tiger());
catHouse2.add(new Mammal());
catHouse2.add(new Animal()); //ERROR
ArrayList<? extends Mammal> catHouse3 = new ArrayList<Mammal>();
catHouse3.add(new Lion()); //ERROR
catHouse3.add(new Tiger()); //ERROR
catHouse3.add(new Mammal()); //ERROR
catHouse3.add(new Animal()); //ERROR
ArrayList<Mammal> zooMammals = new ArrayList<Mammal>();
zooMammals.addAll(catHouse1);
zooMammals.addAll(catHouse2); //ERROR
zooMammals.addAll(catHouse3);
ArrayList<Animal> zooAnimals = new ArrayList<Animal>();
zooAnimals.addAll(catHouse1);
zooAnimals.addAll(catHouse2); //ERROR
zooAnimals.addAll(catHouse3);
}
}
В приведенном выше примере я делаю иерархию классов. Животное - это суперкласс Mammal and Reptile, а Mammal - суперкласс Lion и Tiger.
Я делаю ArrayLists для трех домов кошки в зоопарке. Первый - это просто ArrayList < Млекопитающее>. Я могу добавить любой объект типа Mammal или его подклассы.
Во-вторых, ArrayList <? супер млекопитающее>. Я также могу добавить любой объект типа Mammal или его подклассы.
Третий ArrayList <? распространяет млекопитающее>. Я ничего не могу добавить к этому.
Наконец, я добавляю свои три дома для кошек в коллекции зоопарков. Животные и млекопитающие являются главными суперклассами здесь, и поведение одинаково независимо от того, какой тип хранит ArrayList получателя. ArrayList < Mammal> и ArrayList могут быть добавлены в зоопарки. ArrayList не может.
Вот мои вопросы:
1) Если я хочу, чтобы создать массив, который содержит все подклассы определенного суперкласса, зачем мне нужен подстановочные? Не могу я просто объявить все ArrayList < Суперкласс> и получить необходимую мне функциональность?
2) Я понимаю, что «<? Extends superclass>» принимает суперкласс и все его подклассы. Ergo, <? простирается Млекопитающее> «принимает млекопитающих, львов и тигров. Это звучит точно так же, как« < Млекопитающее ». В чем разница?
3) Я прочитал, что« <? super className> "принимает любой класс, который является суперклассом классаName. Это звучит не так. В приведенном выше примере Lions не являются суперклассами млекопитающих, но« <? супер млекопитающее> "принимает Львы. Животные - суперклассы Млекопитающих, но" <? супер млекопитающее> «не принимает его. Я думаю, что у меня есть неправильная информация.
4) Если« <? extends superclass> "доступен только для чтения, как я могу его заполнить? И в чем смысл иметь пустой список, из которого вы можете только читать?
5) Почему метод addAll не работает на« < ? super className> "?
Я знаю, что это фундаментальные вопросы, и я понимаю, что они уже ответили. Я пытаюсь привести пример кода как можно более простым и, надеюсь, получить ответ, который так же ясен, как и возможно. заранее спасибо за любые советы вы можете предложить.
http://docs.oracle.com/javase/tutorial/java/generics/ – Basilevs