Generics

in

JAVA

Автор Анна Ивницкая

Что такое обобщения?


Обобщения (generics) - это параметризированные типы.


Достоинства обобщений:

  • Обеспечивают безопасность типов на этапе компиляции
  • Операции приведения типов выполяются автоматически и неявно
  • Позволят использовать один алгоритм для разных типов данных

JAVA до версии 5.0



                class Box {
                    private Object item;
                    public void setItem (Object o) {
                        item = o;
                    }
                    public Object getItem () {
                        return item;
                    }
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box box = new Box();
                        box.setItem("hello");
                        String str1 = (String)box.getItem();
                        System.out.println(str1);
                    }
                }
            

Результат выполнения: hello

Ошибка выполнения

                class Box {
                    private Object item;
                    public void setItem (Object o) {
                        item = o;
                    }
                    public Object getItem () {
                        return item;
                    }
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box box = new Box();
                        box.setItem("hello");
                        Integer int1 = (Integer)box.getItem();//Exception
                        System.out.println(int1);
                    }
                }
            
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

JAVA 5.0


                class Box<T> {
                    private T item;
                    public void setItem (T o) {
                        item = o;
                    }
                    public T getItem () {
                        return item;
                    }
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box<String> box = new Box<String>();
                        box.setItem("hello");
                        String str1 = box.getItem();
                        System.out.println(str1);
                    }
                }
            

Результат выполнения: hello

Ошибка компиляции


                class Box<T> {
                    private T item;
                    public void setItem (T o) {
                        item = o;
                    }
                    public T getItem () {
                        return item;
                    }
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box<String> box = new Box<String>();
                        box.setItem(1234567);//Exception
                        String str1 = box.getItem();
                        System.out.println(str1);
                    }
                }
            
Compilation completed with 1 error Error: java: incompatible types: int cannot be converted to java.lang.String

Обобщения действуют только со ссылочными типами


                Box<int> box = new Box<int>(); //Error!
            

Обобщенный класс с двумя параметрами типа


                class Box<T, V> {
                    private T item;
                    private V item2;

                    public Box(T o, V o2) {
                        item = o;
                        item2 = o2;
                    }
                }
            

Ограниченные типы

Ограничение сверху


                class Box <T extends Number>{
                    private T item;
                    public void setItem (T o) {
                        item = o;
                    }
                    public Integer getIntValue () {
                        return item.intValue();
                    }
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box<Float> box = new Box<>();
                        box.setItem(123.45F);
                        Integer int1 = box.getIntValue();
                        System.out.println(int1);
                    }
                }
            

Применение метасимвольных аргументов


                class Box<Т> {}

                class Human {
                    public void useBox(Box<?> box) {}
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box<String> stringBox = new Box<>();
                        Box<Number> numberBox = new Box<>();

                        Human human = new Human();

                        human.useBox(stringBox);
                        human.useBox(numberBox);
                    }
                }
            

Обобщенные интерфейсы


                interface Box<Т> {
                    setItem(T item);
                }

                class BoxImpl implements Box<String> {
                    public void setItem(String item) {}
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box<String> stringBox = new BoxImpl<>();
                        stringBox.setItem("Hello World");
                    }
                }
            

Иерархия обобщенных классов


                class Box<Т> {
                    public void setItem (T item) {}
                }

                class BigBox<K, T> extends Box<T> {
                    public void setBigItems(K item, T item2) {}
                }
            

                public class Test {
                    public static void main(String[] args) {
                        BigBox<String, Integer> stringBox = new BigBox<>();
                        stringBox.setItem("Very big item", 23);
                    }
                }
            

Старый код и обобщенные классы


                class Box<Т> {
                    private T item;
                    public void setItem (T item) {
                        this.item = item;
                    }
                    public T getItem() {
                        return item;
                    }
                }
            

                public class Test {
                    public static void main(String[] args) {
                        Box box = new Box();
                        box.setItem("string");
                        String str = (String)box.getItem();
                    }
                }
            

Спасибо за внимание