Каждый класс реализует некоторое понятие «счетности». В случае CountingGenerator.Character это повторение символов верхнего и нижнего регистра. Класс CountingGenerator.String использует CountingGenerator.Character для заполнения массива символов, который затем преобразуется в String. Размер массива определяется аргументом конструктора. Обратите внимание на то, что CountingGenerator.String использует базовую конструкцию Generator<java.lang.Character> вместо конкретной ссылки на CountingGenerator.Character.
Следующая тестовая программа использует рефлексию с идиомой вложенных генераторов, что позволяет применять ее для любого набора генераторов, построенного по указанному образцу:
//: arrays/GeneratorsTest.java
import net.mindview.util.*;
public class GeneratorsTest {
public static int size = 10;
public static void test(Class<?> surroundingClass) {
for(Class<?> type : surroundingClass.getClasses()) {
System.out.print(type.getSimpleName() + ": ");
try {
Generator<?> g = (Generator<?>)type.newInstance();
</spoiler> Предполагается, что тестируемый класс содержит серию вложенных объектов Generator, каждый из которых имеет конструктор по умолчанию (то есть без аргументов). Рефлексионный метод getClasses() выдает информацию обо всех вложенных классах. Далее метод test() создает экземпляр каждого генератора и выводит результаты, полученные при десятикратном вызове next(). Следующий набор генераторов основан на случайных числах. Так как конструктор Random инициализируется константой, результаты будут повторяться при каждом запуске программы: