Spec-Zone .ru
спецификации, руководства, описания, API
След: Изучение Языка Java
Урок: (Обновленные) Обобщения
Ограниченные Параметры Типа
Домашняя страница > Изучение Языка Java > (Обновленные) обобщения

Ограниченные Параметры Типа

Могут быть времена, когда Вы хотите ограничить типы, которые могут использоваться в качестве параметров типа в параметризованном типе. Например, метод, который работает на числах, мог бы только хотеть принять экземпляры Number или его подклассы. Это - то, для чего ограниченные параметры типа.

Чтобы объявить ограниченный параметр типа, перечислите имя параметра типа, сопровождаемое extends ключевое слово, сопровождаемое его верхней границей, которая в этом примере является Number. Отметьте что в этом контексте, extends используется в общем смысле означать, что любой "расширяется" (как в классах) или "реализации" (как в интерфейсах).

public class Box<T> {

    private T t;          

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    public <U extends Number> void inspect(U u){
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<Integer>();
        integerBox.set(new Integer(10));
        integerBox.inspect("some text"); // error: this is still String!
    }
}

Изменяя наш универсальный метод, чтобы включать этот ограниченный параметр типа, компиляция теперь перестанет работать, начиная с нашего вызова inspect все еще включает a String:

Box.java:21: <U>inspect(U) in Box<java.lang.Integer> cannot
  be applied to (java.lang.String)
                        integerBox.inspect("10");
                                  ^
1 error

В дополнение к ограничению типов можно использовать, чтобы инстанцировать универсального типа, ограниченные параметры типа позволяют Вам вызывать методы, определенные в границах:

public class NaturalNumber<T extends Integer> {

    private T n;

    public NaturalNumber(T n)  { this.n = n; }

    public boolean isEven() {
        return n.intValue() % 2 == 0;
    }

    // ...
}

Метод isEven вызывает метод intValue, определенный в Integer class через n.

Многократные Границы

Предыдущий пример иллюстрирует использование параметра типа со связанным синглом, но у параметра типа могут быть многократные границы:

<T extends B1 & B2 & B3>

Переменная типа с многократными границами является подтипом всех типов, перечисленных в связанном. Если одной из границ является class, она должна быть определена сначала. Например:

Class A { /* ... */ }
interface B { /* ... */ }
interface C { /* ... */ }

class D <T extends A & B & C> { /* ... */ }

Если связанный A не определяется сначала, Вы получаете ошибку времени компиляции:

class D <T extends B & A & C> { /* ... */ }  // compile-time error

Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Универсальные Методы
Следующая страница: Универсальные Методы и Ограниченные Параметры Типа