Учебники

Java — Generics

Было бы хорошо, если бы мы могли написать единственный метод сортировки, который мог бы сортировать элементы в массиве Integer, массиве String или массиве любого типа, который поддерживает порядок.

Java Универсальные методы и универсальные классы позволяют программистам указывать с помощью одного объявления метода набор связанных методов или с помощью одного объявления класса набор связанных типов соответственно.

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

Используя концепцию Java Generic, мы могли бы написать универсальный метод для сортировки массива объектов, а затем вызвать универсальный метод с массивами Integer, Double-массивами, массивами String и т. Д. Для сортировки элементов массива.

Общие методы

Вы можете написать одно объявление универсального метода, которое можно вызывать с аргументами разных типов. Основываясь на типах аргументов, передаваемых универсальному методу, компилятор обрабатывает каждый вызов метода соответствующим образом. Ниже приведены правила для определения общих методов —

  • Все объявления обобщенных методов имеют раздел параметров типа, ограниченный угловыми скобками (<и>), который предшествует типу возврата метода (<E> в следующем примере).

  • Каждый раздел параметров типа содержит один или несколько параметров типа, разделенных запятыми. Параметр типа, также известный как переменная типа, является идентификатором, который задает имя общего типа.

  • Параметры типа могут использоваться для объявления возвращаемого типа и использования в качестве заполнителей для типов аргументов, передаваемых универсальному методу, которые известны как фактические аргументы типа.

  • Тело универсального метода объявляется как тело любого другого метода. Обратите внимание, что параметры типа могут представлять только ссылочные типы, а не примитивные типы (такие как int, double и char).

Все объявления обобщенных методов имеют раздел параметров типа, ограниченный угловыми скобками (<и>), который предшествует типу возврата метода (<E> в следующем примере).

Каждый раздел параметров типа содержит один или несколько параметров типа, разделенных запятыми. Параметр типа, также известный как переменная типа, является идентификатором, который задает имя общего типа.

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

Тело универсального метода объявляется как тело любого другого метода. Обратите внимание, что параметры типа могут представлять только ссылочные типы, а не примитивные типы (такие как int, double и char).

пример

Следующий пример иллюстрирует, как мы можем напечатать массив другого типа, используя один общий метод —

Live Demo

public class GenericMethodTest {
   // generic method printArray
   public static < E > void printArray( E[] inputArray ) {
      // Display array elements
      for(E element : inputArray) {
         System.out.printf("%s ", element);
      }
      System.out.println();
   }

   public static void main(String args[]) {
      // Create arrays of Integer, Double and Character
      Integer[] intArray = { 1, 2, 3, 4, 5 };
      Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
      Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

      System.out.println("Array integerArray contains:");
      printArray(intArray);   // pass an Integer array

      System.out.println("\nArray doubleArray contains:");
      printArray(doubleArray);   // pass a Double array

      System.out.println("\nArray characterArray contains:");
      printArray(charArray);   // pass a Character array
   }
}

Это даст следующий результат —

Выход

Array integerArray contains:
1 2 3 4 5 

Array doubleArray contains:
1.1 2.2 3.3 4.4 

Array characterArray contains:
H E L L O

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

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

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

пример

Следующий пример иллюстрирует, как extends используется в общем смысле для обозначения «extends» (как в классах) или «Implements» (как в интерфейсах). Этот пример — универсальный метод для возврата самого большого из трех сопоставимых объектов —

Live Demo

public class MaximumTest {
   // determines the largest of three Comparable objects
   
   public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
      T max = x;   // assume x is initially the largest
      
      if(y.compareTo(max) > 0) {
         max = y;   // y is the largest so far
      }
      
      if(z.compareTo(max) > 0) {
         max = z;   // z is the largest now                 
      }
      return max;   // returns the largest object   
   }
   
   public static void main(String args[]) {
      System.out.printf("Max of %d, %d and %d is %d\n\n", 
         3, 4, 5, maximum( 3, 4, 5 ));

      System.out.printf("Max of %.1f,%.1f and %.1f is %.1f\n\n",
         6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ));

      System.out.printf("Max of %s, %s and %s is %s\n","pear",
         "apple", "orange", maximum("pear", "apple", "orange"));
   }
}

Это даст следующий результат —

Выход

Max of 3, 4 and 5 is 5

Max of 6.6,8.8 and 7.7 is 8.8

Max of pear, apple and orange is pear

Универсальные классы

Объявление универсального класса выглядит как объявление неуниверсального класса, за исключением того, что за именем класса следует раздел параметра типа.

Как и в случае универсальных методов, раздел параметров типа универсального класса может иметь один или несколько параметров типа, разделенных запятыми. Эти классы известны как параметризованные классы или параметризованные типы, потому что они принимают один или несколько параметров.

пример

Следующий пример иллюстрирует, как мы можем определить универсальный класс —

Live Demo

public class Box<T> {
   private T t;

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

   public T get() {
      return t;
   }

   public static void main(String[] args) {
      Box<Integer> integerBox = new Box<Integer>();
      Box<String> stringBox = new Box<String>();
    
      integerBox.add(new Integer(10));
      stringBox.add(new String("Hello World"));

      System.out.printf("Integer Value :%d\n\n", integerBox.get());
      System.out.printf("String Value :%s\n", stringBox.get());
   }
}

Это даст следующий результат —