Ограничение &
Ограничение & (ampersand bound, или intersection type) в дженериках Java
позволяет указать, что параметр типа должен удовлетворять сразу нескольким
интерфейсам одновременно. Такое ограничение записывается через символ &
между типами. В первом параметре ограничения указывается первый интерфейс,
во втором - второй интерфейс, и так далее. Если среди ограничений есть класс,
он обязан стоять первым, так как Java не поддерживает множественное наследование
классов. Ограничение & часто применяется в дженерик-методах, чтобы
гарантировать, что переданный объект поддерживает все необходимые операции.
Синтаксис
<T extends Interface1 & Interface2 & Interface3>
Пример
Давайте создадим два интерфейса и дженерик-метод, который принимает только объекты, реализующие оба интерфейса одновременно:
interface Walkable
{
void walk();
}
interface Swimmable
{
void swim();
}
public class Main
{
public static <T extends Walkable & Swimmable> void act(T obj)
{
obj.walk();
obj.swim();
}
public static void main(String[] args)
{
class Duck implements Walkable, Swimmable
{
public void walk()
{
System.out.println("walking");
}
public void swim()
{
System.out.println("swimming");
}
}
Duck duck = new Duck();
act(duck);
}
}
Результат выполнения кода:
"walking"
"swimming"
Пример
Давайте создадим класс и интерфейс, а затем ограничим дженерик-метод так, чтобы тип был подклассом класса и реализовывал интерфейс. Обратите внимание: класс всегда указывается первым:
interface Named
{
String getName();
}
class Animal
{
public String kind()
{
return "animal";
}
}
public class Main
{
public static <T extends Animal & Named> void print(T obj)
{
System.out.println(obj.kind());
System.out.println(obj.getName());
}
public static void main(String[] args)
{
class Dog extends Animal implements Named
{
public String getName()
{
return "dog";
}
}
Dog dog = new Dog();
print(dog);
}
}
Результат выполнения кода:
"animal"
"dog"
Пример
Давайте посмотрим, что произойдет, если тип не удовлетворяет всем ограничениям одновременно:
interface Walkable
{
void walk();
}
interface Swimmable
{
void swim();
}
public class Main
{
public static <T extends Walkable & Swimmable> void act(T obj)
{
obj.walk();
obj.swim();
}
public static void main(String[] args)
{
class Walker implements Walkable
{
public void walk()
{
System.out.println("walking");
}
}
Walker walker = new Walker();
// act(walker); // ошибка компиляции
}
}
Если раскомментировать строку с вызовом act, компилятор выдаст ошибку,
так как класс Walker реализует только интерфейс Walkable,
но не реализует Swimmable.
Смотрите также
-
ограничение
extends-bound,
которое задает верхнюю границу типа -
ограничение
super-bound,
которое задает нижнюю границу типа -
параметр типа,
который задается в угловых скобках дженерика -
дженерик-метод,
который принимает параметры типа