Java 泛型

在本教程中,我们将通过示例了解Java泛型,如何创建泛型类和方法及其优势。

在Java中,泛型有助于创建可与不同类型的对象(数据)一起使用的类,接口和方法。因此,允许我们重用我们的代码。

意:泛型泛型不适用于基本类型(int,float,char等)。

如何使用Java泛型

要了解在Java中如何使用泛型,我们可以使用ArrayListJava集合框架的类。

ArrayList类是泛型类的一个示例。我们可以使用ArrayList来存储任何类型的数据。例如

importjava.util.ArrayList;classMain{publicstaticvoidmain(String[]args){//创建一个数组列表来存储Integer数据ArrayList<Integer>list1=newArrayList<>();list1.add(4);list1.add(5);System.out.println("ArrayListofInteger:"+list1);//创建数组列表来存储String数据ArrayList<String>list2=newArrayList<>();list2.add("Four");list2.add("Five");System.out.println("ArrayListofString:"+list2);//创建数组列表来存储Double数据ArrayList<Double>list3=newArrayList<>();list3.add(4.5);list3.add(6.5);System.out.println("ArrayListofDouble:"+list3);}}

输出结果

ArrayListofInteger:[4,5]ArrayListofString:[Four,Five]ArrayListofDouble:[4.5,6.5]

在上面的示例中,我们使用了相同的ArrayList类来存储Integer,String和Double类型的元素。 由于Java泛型,这是可能的。

在这里,请注意这行,

ArrayList<Integer>list1=newArrayList<>();

我们在尖括号<>中使用了Integer。 尖括号<>在泛型中称为类型参数

参数type用于指定泛型类或方法适用的对象(数据)的类型。

创建泛型类

现在我们知道了泛型在Java中的工作方式,让我们看看如何创建自己的泛型类。

示例:创建泛型类

classMain{publicstaticvoidmain(String[]args){//用整数数据初始化泛型类GenericsClass<Integer>intObj=newGenericsClass<>(5);System.out.println("泛型类返回:"+intObj.getData());//用字符串数据初始化泛型类GenericsClass<String>stringObj=newGenericsClass<>("JavaProgramming");System.out.println("泛型类返回:"+stringObj.getData());}}classGenericsClass<T>{//T型变量privateTdata;publicGenericsClass(Tdata){this.data=data;}//返回T类型变量的方法publicTgetData(){returnthis.data;}}

输出结果

泛型类返回:5泛型类返回:JavaPrograming

在上面的示例中,我们创建了一个名为GenericsClass的泛型类。此类可用于处理任何类型的数据。

classGenericsClass<T>{...}

在此,T表示类型参数。 在Main类内部,我们创建了名为intObj和stringObj的GenericsClass对象。

  • 在创建intObj时,类型参数T被Integer替换。这意味着intObj使用GenericsClass处理整数数据。

  • 在创建stringObj时,类型参数T被String替换。 这意味着stringObj使用GenericsClass处理字符串数据。

创建泛型方法

与泛型类相似,我们还可以在Java中创建自己的泛型方法。

示例:创建泛型方法

classMain{publicstaticvoidmain(String[]args){//使用Integer数据初始化类DemoClassdemo=newDemoClass();demo.<String>genericsMethod("JavaProgramming");}}classDemoClass{//泛型方法public<T>voidgenericsMethod(Tdata){System.out.println("这是一个泛型方法。");System.out.println("传递给方法的数据是"+data);}}

输出结果

这是一个泛型方法。传递给方法的数据是:JavaProgramming

在上面的示例中,我们创建了一个在普通类(DemoClass)内部命名的泛型方法genericsMethod。

public<T>voidgenericMethod(Tdata){...}

在此,将类型参数<T>插入到修饰符(public)之后和返回类型(void)之前。

我们可以通过将实际类型<String>放在方法名前面的括号中来调用泛型方法。

demo.<String>genericMethod("JavaProgramming");

注意:在大多数情况下,我们可以在调用泛型方法时省略type参数。这是因为编译器可以使用传递给方法的值来匹配类型参数。例如,

demo.genericsMethod("JavaProgramming");

有界类型

通常,type参数可以接受任何数据类型(原始类型除外)。但是,如果我们只想将泛型用于某些特定类型(例如接受数字类型的数据),则可以使用有界类型。

我们使用extends关键字。例如,

<TextendsA>

这意味着T只能接受A的子类型的数据。

示例:有界类型

classGenericsClass<TextendsNumber>{publicvoiddisplay(){System.out.println("Thisisaboundedtypegenericsclass.");}}classMain{publicstaticvoidmain(String[]args){//创建一个GenericsClass对象GenericsClass<String>obj=newGenericsClass<>();}}

在上面的示例中,我们创建了一个有界类型的泛型类。 在这里,请注意表达式

<TextendsNumber>

这意味着T只能使用Number的子级数据类型(Integer,Double等)。

但是,我们已经用String创建了泛型类的对象。这就是为什么当我们运行程序时,我们会得到以下错误。

GenericsClass<String>obj=newGenericsClass<>();^reason:inferencevariableThasincompatibleboundsequalityconstraints:Stringlowerbounds:NumberwhereTisatype-variable:TextendsNumberdeclaredinclassGenericsClass

Java泛型的优点

1.代码可复用性

泛型使我们能够编写适用于不同类型数据的代码。例如,

public<T>voidgenericsMethod(Tdata){...}

在这里,我们创建了一个泛型方法。此方法可用于对整数数据,字符串数据等执行操作。

2.编译时类型检查

泛型的type参数提供有关泛型代码中使用的数据类型的信息。

因此,可以在编译时识别任何错误,比运行时错误更容易修复。例如,

//不使用泛型NormalClasslist=newNormalClass();//调用NormalClass的方法list.display("String");

在上面的代码中,我们有一个普通的类。我们通过传递字符串数据来调用此类的名为display()的方法。

在这里,编译器不知道在参数中传递的值是否正确。但是,让我们看看如果改用泛型类会发生什么。

//使用泛型GenericsClass<Integer>list=newGenericsClass<>();//调用GenericsClass的方法list2.display("String");在上面的代码中,我们有一个泛型类。在这里,类型参数表示该类正在处理Integer数据。因此,当字符串数据在参数中传递时,编译器将生成一个错误。

3.泛型与集合一起使用

集合框架使用Java中的泛型概念。例如,

//创建一个字符串类型ArrayListArrayList<String>list1=newArrayList<>();//创建一个整数类型ArrayListArrayList<Integer>list2=newArrayList<>();

在上面的示例中,我们使用了相同的ArrayList类来处理不同类型的数据。

类似ArrayList,其他集合(LinkedList,Queue,Maps,等等)也是Java的泛型。

编辑于2024-05-20 15:23