public List<Class<? extends Pet>> getTypes() {return types;}
public static void main(String[] args) {
System.out.println(types);
}
}
<spoiler text="Output:">
[class typeinfo pets.Mutt, class typeinfo.pets.Pug, class typeinfo.pets.EgyptianMau. class
typeinfo pets Manx, class typeinfo.pets.Cymric, class typeinfo.pets.Rat, class
typeinfo.pets.Mouse, class typeinfo.pets.Hamster]
</spoiler> В будущем примере PetCount3.java контейнер Map заполняется всеми типами Pet (не только генерируемыми случайным образом), поэтому нам понадобился список allTypes. Список types представляет собой часть allTypes (создается вызовом List.subList()) со всеми типами Pet, поэтому он используется для случайного генерирования Pet. На этот раз при создании types блок try не нужен, так как необходимые проверки типов проводятся еще во время компиляции и исключения не возбуждаются, в отличие от методаClass.forName(). Теперь библиотека typeinfo.pets содержит две реализации PetCreator. Чтобы вторая реализация использовалась по умолчанию, мы можем создать фасад (façade), использующий LiteralPetCreator:
//• typeinfo/pets/Pets.java
// Фасад для получения PetCreator по умолчанию
package typeinfo.pets;
import java.util.*;
public class Pets {
public static final PetCreator creator = new LiteralPetCreator();
public static Pet randomPet() {return creator.randomPet();};
public static Pet[] createArray(int size)
{return creator.createArray(size);}
public static ArrayList<Pet> arrayList(int size)
{return creator.arrayList(size);}
}
При этом также обеспечиваются косвенные вызовы randomPet(), createArray() и arrayList(). Поскольку PetCount.countPets() получает аргумент PetCreator, мы можем легко проверить работу LiteralPetCreator (через представленный фасад):
// typeinfo/PetCount2.java
package typeinfo;
import typeinfo.pets.*;
public class PetCount2 {
public static void main(String[] args) {
PetCount.countPets(Pets.creator);
}
}
/* (Выполните, чтобы увидеть результат) */
//:- Результат будет таким же, как у PetCount.java.