English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
在本教程中,我们将通过示例了解Java泛型,如何创建泛型类和方法及其优势。
在Java中,Generic有助于创建可与不同类型的对象(数据)一起使用的类,接口和方法。因此,允许我们重用我们的代码。
注意:Generic泛型不适用于基本类型(int,float,char等)。
要了解在Java中如何使用Generic,我们可以使用ArrayListJava集合框架的类。
ArrayList类是泛型类的一个示例。我们可以使用ArrayList来存储任何类型的数据。例如
import java.util.ArrayList; class Main { public static void main(String[] args) { //创建一个数组列表来存储Integer 数据 ArrayList<Integer> list1 = new ArrayList<>(); list1.add(4); list1.add(5); System.out.println("ArrayList of Integer: " + list1); //创建数组列表来存储String 数据 ArrayList<String> list2 = new ArrayList<>(); list2.add("Four"); list2.add("Five"); System.out.println("ArrayList of String: " + list2); //创建数组列表来存储Double 数据 ArrayList<Double> list3 = new ArrayList<>(); list3.add(4.5); list3.add(6.5); System.out.println("ArrayList of Double: " + list3); } }
Результат вывода
ArrayList of Integer: [4, 5] ArrayList of String: [Four, Five] ArrayList of Double: [4.5, 6.5]
В предыдущем примере мы использовали один и тот же класс ArrayList для хранения элементов типа Integer, String и Double. Из-заJava generics, это возможно.
Здесь, пожалуйста, обратите внимание на эту строку,
ArrayList<Integer> list1 = new ArrayList<>();
Мы использовали Integer в尖括никах <> .尖括ники <> в generics называютсяПараметры типа.
Параметр type используется для указания типа объекта (данных), который подходит для generics класса или метода.
Теперь мы знаем, как generics работают в Java, давайте посмотрим, как создать свой generics класс.
class Main { public static void main(String[] args) { //Инициализация generics класса целочисленными данными GenericsClass<Integer> intObj = new GenericsClass<>(5); System.out.println("Generic class returns: " + intObj.getData()); //Инициализация generics класса строковыми данными GenericsClass<String> stringObj = new GenericsClass<>("Java Programming"); System.out.println("Generic class returns: " + stringObj.getData()); } } class GenericsClass<T> { //Переменная типа T private T data; public GenericsClass(T data) { this.data = data; } //Метод для возврата переменной типа T public T getData() { return this.data; } }
Результат вывода
Generic class возвращает: 5 Generic class возвращает: Java Programing
В предыдущем примере мы создали класс GenericsClass, который является generics классом. Этот класс может обрабатывать данные любого типа.
class GenericsClass<T> {...}
Здесь T означаетПараметры типаВнутри класса Main мы создали объекты GenericsClass с именами intObj и stringObj.
При создании intObj типовой параметр T заменяется на Integer. Это означает, что intObj использует GenericsClass для обработки целых данных.
При создании stringObj типовой параметр T заменяется на String. Это означает, что stringObj использует GenericsClass для обработки строковых данных.
Как и generics классы, мы можем создавать свои generics методы в Java.
class Main { public static void main(String[] args) { // использование Integer для инициализации класса DemoClass demo = new DemoClass(); demo.<String>genericMethod("Java Programming"); } } class DemoClass { // generics метод public <T> void genericMethod(T data) { System.out.println("Это generics метод."); System.out.println("Переданные методу данные: " + data); } }
Результат вывода
Это generics метод. Переданные методу данные: Java Programming
В примере выше мы создали generics метод genericsMethod в обычном классе (DemoClass).
public <T> void genericMethod(T data) {...}
Здесь типовой параметр <T> вставлен после модификатора (public) и перед типом возвращаемого значения (void).
Мы можем вызвать generics метод, поместив фактический тип <String> перед именем метода в скобках.
demo.<String>genericMethod("Java Programming");
Внимание: В большинстве случаев мы можем опустить параметр типа при вызове generics метода. Это потому, что компилятор может использовать переданные значения для соответствия параметрам типа. Например:
demo.genericsMethod("Java Programming");
Обычно:Параметр typeМожет приниматьany тип данных (за исключением примитивных типов). Но если мы хотим использовать generics только для некоторых специфических типов (например, принимать данные типа Number), то можно использовать ограниченные типы.
Мы используем ключевое слово extends. Например:
<T extends A>
Это означает, что T может принимать только подтипы данных A.
class GenericsClass<T extends Number> { public void display() {}} System.out.println("This is a bounded type generics class."); } } class Main { public static void main(String[] args) { //Создание объекта GenericsClass GenericsClass<String> obj = new GenericsClass<>(); } }
В приведенном выше примере мы создалиограниченные типыGeneric class. Здесь обратите внимание на выражение
<T extends Number>
Это означает, что T может использовать только подтипы данных subclasses Number (Integer, Double и т.д.).
Но我们已经 создали объект класса generics с помощью String. Вот почему, когда мы запускаем программу, мы получаем следующую ошибку.
GenericsClass<String> obj = new GenericsClass<>(); ^ причина: переменная типа inference variable T имеет несовместимые границы ограничения равенства: String нижние границы: Number where T is a type-variable: T extends Number declared in class GenericsClass
GenericЭто позволяет нам писать код, подходящий для данных различных типов. Например:
public <T> void genericsMethod(T data) {...}
Здесь мы создаем метод generics. Этот метод может использоваться для выполнения операций с данными целых чисел, строк и т.д.
GenericПараметр typeПредоставление информации о типах данных, используемых в коде generics.
Таким образом, можно определить любые ошибки в компиляции, что проще исправить, чем ошибки во время выполнения. Например:
//Не использовать generics NormalClass list = new NormalClass(); //Вызов метода NormalClass list.display("String");
В приведенном выше коде у нас есть обычный класс. Мы вызываем метод display() этого класса, передавая строковые данные.
Здесь компилятор не знает, правильны ли передаваемые значения в параметрах. Но посмотрим, что произойдет, если использовать классы-генерики.
//Использование generics GenericsClass<Integer> list = new GenericsClass<>(); // Вызов метода GenericsClass list2.display("String"); В приведенном выше коде у нас есть генерический класс. Здесь типовые параметры представляют собой данные Integer, обрабатываемые этим классом. Таким образом, при передаче строковых данных в параметрах компилятор генерирует ошибку.
Контейнерный интерфейс использует концепцию генериков Java. Например:
// Создать ArrayList типа string ArrayList<String> list1 = new ArrayList<>(); // Создать ArrayList типа integer ArrayList<Integer> list2 = new ArrayList<>();
В приведенном выше примере мы используем один и тот же класс ArrayList для обработки различных типов данных.
Как и ArrayList, другие коллекции (LinkedList, Queue, Maps и т.д.) также являются генериками Java.