Конструкция ограничивает сверху множество типов, пригодных для настройки параметра T. Таким же образом, написав , можно ограничить снизу тип T только типом SomeClass и его супертипами.
У настраиваемого типа может быть более одного параметра. Они перечисляются в угловых скобках через запятую:
class MyGenericClass2{ private S id; private T data;
public MyGenericClass2() {}
public MyGenericClass2(S id, T data){ this.id = id; this.data = data;
}
public S getId(){ return id;
}
public void setId(S data){ this.id = id;
}
public T getData(){ return data;
}
public void setData(T data){ this.data = data;
}
}
Из этих примеров видно, что неопределенные типы S, T могут быть типами параметров конструкторов и типами возвращаемых методами значений. Разумеется, они могут быть типами параметров не только конструкторов, но и любых методов. Более того, типами параметров и типами возвращаемых значений методов могут быть настраиваемые типы. Можно написать метод в такой форме:
public MyGenericClass2 makeClass2(S id,
MyGenericClass data){ return new MyGenericClass2(id, data.getData());
}
и обратиться к нему так, как показано в листинге 4.3.
Листинг 4.3. Настраиваемые классы — параметры методов
public class MyGenericClass2Demo{
public MyGenericClass2
makeClass2(S id, MyGenericClass data){
return new MyGenericClass2(id, data.getData());
}
public static void main(String[] args){
MyGenericClass dMyGen = new MyGenericClass<>(34.456);
MyGenericClass2Demo d = new MyGenericClass2Demo<>();
MyGenericClass2 ldMyGen2 = d.makeClass2(123456L, dMyGen);
}
}
Шаблон типа (wildcard type)
В предыдущих главах мы часто пользовались тем, что можно определить ссылку типа суперкласса, ссылающуюся на объект подкласса, например:
Number n = new Long(123456L);
Number d = new Double(27.346);
Более того, это свойство распространяется на массивы:
Number[] n = new Long[100];
Можно ли распространить эту возможность на настраиваемые типы? Например, можно ли написать последний оператор листинга 4.3 так:
MyGenericClass2 n = // Сшибка!
d.makeClass2(123456L, dMyGen);
Ответ отрицательный. Из того, что какой-то класс B является подклассом класса A, не следует, что класс g будет подклассом класса g.
Это непривычное обстоятельство вынудило ввести дополнительную конструкцию — шаблон типа (wildcard type), применяемую в процессе настройки типа. Шаблон типа обозначается вопросительным знаком и означает "неизвестный тип" или "произвольный тип". Предыдущий код не вызовет возражений у компилятора, если написать его в таком виде:
MyGenericClass2 n =
d.makeClass2(123456L, dMyGen);
Такая запись будет почти эквивалентна записи
MyGenericClass2 n =
d.makeClass2(123456L, dMyGen);
за тем исключением, что в первом случае компилятор сделает более строгие проверки.
Кроме записи [10];
Настраиваемые методы
Настраиваемыми могут быть не только типы, но и методы. Параметры настраиваемого метода (type parameters) указываются в заголовке метода в угловых скобках перед типом возвращаемого значения. Это выглядит так, как показано в листинге 4.4.
Листинг 4.4. Настраиваемый метод
public class MyGenericClass2Demo{
public MyGenericClass2
makeClass2(S id, MyGenericClass data){
return new MyGenericClass2(id, data.getData());
} public static void main(String[] args){
MyGenericClass dMyGen = new MyGenericClass(34.456);
MyGenericClass2Demo d =
new MyGenericClass2Demo();
MyGenericClass2 ldMyGen2 = d.makeClass2(123456L, dMyGen);
}
}
Метод makeClass2 () описан в простом, ненастраиваемом, классе MyGenericClass2Demo, и его параметры задаются в угловых скобках . Здесь можно записывать ограниченные параметры
public
MyGenericClass2 makeClass2(S id, MyGenericClass data){
return new MyGenericClass2(id, data.getData());
}
Как видно из листинга 4.4, специально настраивать метод не нужно, конкретные типы его параметров и возвращаемого значения определяются компилятором по переданным в метод аргументам.
Как вы убедились из приведенных примеров, настраиваемые типы и методы допускают сложную структуру параметров, так же как и вложенные классы. Мы еще не касались вопросов наследования настраиваемых типов, реализации настраиваемых интерфейсов, создания массивов настраиваемых типов. Все эти вопросы подробно рассмотрены на сайте Анжелики Лангер (Angelika Langer), в ее Java Generics FAQ, http://
www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html.
Читать дальше
Конец ознакомительного отрывка
Купить книгу