Рубрики

Обобщения в Java

Обобщения в Java похожи на шаблоны в C ++ . Идея состоит в том, чтобы позволить типу (Integer, String,… и т. Д. И пользовательским типам) быть параметром для методов, классов и интерфейсов. Например, классы, такие как HashSet, ArrayList, HashMap и т. Д., Очень хорошо используют дженерики. Мы можем использовать их для любого типа.

Общий класс

Как и в C ++, мы используем <> для указания типов параметров при создании универсального класса. Для создания объектов универсального класса мы используем следующий синтаксис.

// To create an instance of generic class 
BaseType <Type> obj = new BaseType <Type>()

Note: In Parameter type we can not use primitives like 
      'int','char' or 'double'.

// Простая Java-программа, показывающая работу пользователя
// Общие классы

   
// Мы используем <> для указания типа параметра

class Test<T>

{

    // Объект типа T объявлен

    T obj;

    Test(T obj) {  this.obj = obj;  }  // конструктор

    public T getObject()  { return this.obj; }

}

   
// Класс драйвера для тестирования выше

class Main

{

    public static void main (String[] args)

    {

        // экземпляр типа Integer

        Test <Integer> iObj = new Test<Integer>(15);

        System.out.println(iObj.getObject());

   

        // экземпляр типа String

        Test <String> sObj =

                          new Test<String>("GeeksForGeeks");

        System.out.println(sObj.getObject());

    }

}

Выход:

15
GeeksForGeeks

Мы также можем передать несколько параметров типа в общие классы.

// Простая Java-программа для отображения нескольких
// введите параметры в Java Generics

  
// Мы используем <> для указания типа параметра

class Test<T, U>

{

    T obj1;  // Объект типа T

    U obj2;  // Объект типа U

  

    // конструктор

    Test(T obj1, U obj2)

    {

        this.obj1 = obj1;

        this.obj2 = obj2;

    }

  

    // Для печати объектов T и U

    public void print()

    {

        System.out.println(obj1);

        System.out.println(obj2);

    }

}

  
// Класс драйвера для тестирования выше

class Main

{

    public static void main (String[] args)

    {

        Test <String, Integer> obj =

            new Test<String, Integer>("GfG", 15);

  

        obj.print();

    }

}

Выход:

GfG
15

Общие функции:

Мы также можем написать универсальные функции, которые можно вызывать с различными типами аргументов, в зависимости от типа аргументов, передаваемых универсальному методу, компилятор обрабатывает каждый метод.

// Простая Java-программа, показывающая работу пользователя
// Общие функции

   

class Test

{

    // Пример общего метода

    static <T> void genericDisplay (T element)

    {

        System.out.println(element.getClass().getName() +

                           " = " + element);

    }

   

    // Метод драйвера

    public static void main(String[] args)

    {

         // Вызов универсального метода с аргументом Integer

        genericDisplay(11);

   

        // Вызов универсального метода с аргументом String

        genericDisplay("GeeksForGeeks");

   

        // Вызов универсального метода с двойным аргументом

        genericDisplay(1.0);

    }

}

Выход :

java.lang.Integer = 11
java.lang.String = GeeksForGeeks
java.lang.Double = 1.0

Преимущества дженериков:

Программы, использующие Generics, имеют много преимуществ по сравнению с неуниверсальным кодом.

  1. Повторное использование кода: мы можем написать метод / класс / интерфейс один раз и использовать для любого типа, который мы хотим.
  2. ,

  3. Безопасность типов: Generics допускает появление ошибок во время компиляции, а не во время выполнения (всегда лучше знать проблемы в вашем коде во время компиляции, а не заставлять ваш код отказывать во время выполнения). Предположим, вы хотите создать ArrayList, в котором хранятся имена учеников, и если по ошибке программист добавляет целочисленный объект вместо строки, компилятор позволяет это. Но когда мы получаем эти данные из ArrayList, это вызывает проблемы во время выполнения.

    // Простая Java-программа, демонстрирующая, что НЕ использует
    // Обобщения могут вызывать исключения во время выполнения

    import java.util.*;

      

    class Test

    {

        public static void main(String[] args)

        {

            // Создание ArrayList без указания типа

            ArrayList al = new ArrayList();

      

            al.add("Sachin");

            al.add("Rahul");

            al.add(10); // Компилятор позволяет это

      

            String s1 = (String)al.get(0);

            String s2 = (String)al.get(1);

      

            // Вызывает исключение во время выполнения

            String s3 = (String)al.get(2);

        }

    }

    Выход :

    Exception in thread "main" java.lang.ClassCastException: 
       java.lang.Integer cannot be cast to java.lang.String
    	at Test.main(Test.java:19)

    Как дженерики решают эту проблему?
    Во время определения ArrayList мы можем указать, что этот список может принимать только объекты String.

    // Использование обобщений преобразует исключения времени выполнения в
    // исключение времени компиляции.

    import java.util.*;

      

    class Test

    {

        public static void main(String[] args)

        {

            // Создание ArrayList с указанным String

            ArrayList <String> al = new ArrayList<String> ();

      

            al.add("Sachin");

            al.add("Rahul");

      

            // Теперь компилятор не позволяет этого

            al.add(10); 

      

            String s1 = (String)al.get(0);

            String s2 = (String)al.get(1);

            String s3 = (String)al.get(2);

        }

    }

    Выход:

    15: error: no suitable method found for add(int)
            al.add(10); 
              ^
  4. ,

  5. Отдельное приведение типов не требуется: если мы не используем обобщенные типы, то в приведенном выше примере каждый раз, когда мы получаем данные из ArrayList, мы должны типизировать их. Типирование при каждой операции поиска — большая головная боль. Если мы уже знаем, что наш список содержит только строковые данные, нам не нужно вводить их каждый раз.

    // Нам не нужно типизировать отдельных членов ArrayList

    import java.util.*;

      

    class Test

    {

        public static void main(String[] args)

        {

            // Создание ArrayList с указанным String

            ArrayList <String> al = new ArrayList<String> ();

      

            al.add("Sachin");

            al.add("Rahul");

      

            // Типизация не нужна

            String s1 = al.get(0);

            String s2 = al.get(1);

        }

    }

  6. ,

  7. Реализация универсальных алгоритмов. Используя универсальные алгоритмы, мы можем реализовать алгоритмы, которые работают с различными типами объектов, и в то же время они также безопасны для типов.

Ссылки:
https://docs.oracle.com/javase/tutorial/java/generics/why.html

Эта статья предоставлена Dharmesh Singh . Если вам нравится GeeksforGeeks и вы хотите внести свой вклад, вы также можете написать статью и отправить ее по почте на contrib@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Обобщения в Java

0.00 (0%) 0 votes