您的位置 首页 java

Java面试重要考点攻克:如何在Java中使用泛型?

Java面试重要考点攻克:如何在Java中使用泛型?

图源:unsplash

作为 Java 中关键概念,大多数Java代码库都会使用 泛型 ,开发人员在某个时候遇到它们也是不可避免的。正确理解泛型对于掌握Java至关重要,这也会对你的面试有所助益。

本文是关于Java中泛型知识的大放送,泛型是什么,如何在Java中使用,以及它们的优点有哪些,你都能在下文中找到答案。

在Java 5中添加泛型是为了提供编译时类型检查,并消除使用集合类时常见的 ClassCastException 风险。Java中的集合类用于存储和操作对象组。例如,ArrayList集合类可以存储任何类型的对象。因为它被设计成Java基类类型对象的容器。

因此,ArrayList对象可以保存 字符串 、整数或任何Java类型。在泛型之前,只创建字符串或整数的ArrayList是不可行的。使用泛型定义ArrayList可以容纳的对象类型,因此允许创建单个的ArrayList对象类型:

 import java.util.ArrayList;
                            publicclassGenEx1{
                                 publicstaticvoidmain(String []args){
                                     ArrayList<String> al =newArrayList<String>();
                                     al.add("Name");
                                     al.add("Age");
                                     al.add(22); // Compile Error!
                                 }
                            }  

如上例,泛型类型是通过使用尖括号定义的。在本例中,只有String对象可以存储在ArrayList中。Java中的集合类现在具有泛型类型。接下来,让我们来看看如何编写自己的泛型类、接口和方法。

Java面试重要考点攻克:如何在Java中使用泛型?

泛型类

在泛型类声明中,类的名称后面是类型参数部分。可以使用相同的语法来创建通用接口。类型参数,也称为类型变量,是用于指定泛型类型名称的标识符。泛型类的类型参数部分可以包括一个或多个用逗号分隔的类型参数,这些类也称为参数化类。

 classTest<K, V>{
              private K key;
              private V value;
                         Test(K key, V value){
                  this.key = key;
                  this.value = value;
              }
                         public K getKey(){
                  return key;
              }
              public V getValue(){
                  return value;
              }
                     }
          publicclassGenEx2{
               publicstaticvoidmain(String []args){
                   Test<String, Integer > pair1 =newTest<String,Integer>("ID",223);
                   Test<String,Integer> pair2 =newTest<String,Integer>("Age",22);
                   System.out.println(pair1.getKey() +"="+ pair1.getValue() );
                   System.out.println(pair2.getKey() +"="+ pair2.getValue() );
               }
          }  

在上例中,测试类有两个名为K和 v的类型参数,因此测试类的对象可以存储两种不同类型的值。

Java面试重要考点攻克:如何在Java中使用泛型?

泛型方法

如果可以编写一个排序方法来对整数数组、字符串数组或任何支持排序的类型的数组中的元素进行排序,该有多好?

Java面试重要考点攻克:如何在Java中使用泛型?

图源:unsplash

Java泛型方法允许用一个方法声明指定一组相关类型。这样能够编写单个泛型方法声明,该声明可以用不同类型的参数调用。类型参数部分必须在方法返回类型之前指定,类型参数也可以用作方法的返回类型。

 publicclassGenEx3{
                          publicstatic< E >voidprintArray( E[] inputArray ) {
                    for(E element : inputArray) {
                        System.out.print(element +" ");
                    }
                    System.out.println();
               }
                publicstaticvoidmain(String args[]){
                    Integer[] intArray = { 1, 2, 3, 4, 5 };
                    Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
                    Character[] charArray = { 'P', 'I', 'Z', 'Z', 'A' };
                   System.out.print("integerArray contains: ");
                    printArray(intArray);
                    System.out.print("doubleArray contains: ");
                    printArray(doubleArray);
                    System.out.print("characterArray contains: ");
                    printArray(charArray);
                 }
            }  

在上例中, printArray 方法可以用来打印任何类型数组的元素。

Java面试重要考点攻克:如何在Java中使用泛型?

泛型中的有界类型参数

到目前为止,我们只看到了无界泛型类型参数。无界意味着泛型类型参数可以是我们想要的任何类型,有时可能需要限制允许传递给类型参数的类型。例如,对数字进行操作的方法可能只想接受 Number 类或其子类的实例,为此使用了有界类型参数。

若要声明有界类型参数,要列出类型参数的名称,后跟extends关键字,然后是它的 上界

 publicabstractclassCage<T extendsAnimal> {
               abstractvoidaddAnimal(T animal)
           }
           classAnimal{}
           classDogextendsAnimal{}
           classCatextendsAnimal{}  

在本例中,Cage类的泛型类型必须始终是Animal或Animal类的一个子类。因此,我们可以将Cat、Dog或Animal类作为泛型类型参数传递。如果需要,还可以为泛型类型声明多个界限。上面示例中的抽象类可以按照如下所示进行修改:

 public abstract class Cage<T extends Animal& Comparable<T>>  

在这里,类型参数现在必须同时考虑Animal类和Comparable接口。

Java面试重要考点攻克:如何在Java中使用泛型?

泛型中的通配符和子类型

问号(?)是泛型中的通配符,表示未知类型。如果希望泛型方法处理所有类型,在本例中可以使用无界通配符。无界通配符由<?>表示,还可以使用绑定通配符。有界通配符有两种类型,上界通配符和下界通配符。

Java面试重要考点攻克:如何在Java中使用泛型?

图源:unsplash

上界通配符用于放宽对方法中变量类型的限制。例如,假设不知道list是数字、整数还是Double类型。那么如何得到列表中所有元素的和呢?可以使用上界通配符来解决这个问题:

 publicvoid method( List<? extends Number> list){
                       double sum =0;
                       for(Number i : list){
                        sum += i.doubleValue();
                       }
                       System.out.println(sum);
                     }  

下界通配符用于增加对方法中变量类型的限制。假设只想向一个列表中添加整数,同时又想接受一个Integer超类型的列表。可以使用一个下界通配符来实现这一点:

 publicvoid addIntegers(List<? super Integer> list){
                            list.add(new Integer(10));
                            list.add(new Integer(20));
                           }  

虽然 Integer 是Java中 Number 的子类型,但是 List<Integer> 不是 List<Number> 的子类型。它们的共同父类是List<?>。所以泛型类中的子类型是使用通配符完成的:

 ArrayList<? extends Integer> intList =newArrayList<>();
                     ArrayList<? extends Number> numList = intList; // OK
           ArrayList<Integer> intList2 =newArrayList<>();
                     ArrayList<Number> numList2 = intList2; // Compile Error!  

diamond操作符,也称为diamond语法,是作为Java 7中的一个新特性引入的。diamond操作符的目的是在创建对象时简化泛型的使用。

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

通过使用diamond操作符,可以简化字符串ArrayList的声明。

Java面试重要考点攻克:如何在Java中使用泛型?

泛型的好处

讲过如何使用泛型之后,让我们来探讨一下,我们为何要使用泛型呢?使用泛型有三个主要原因:

· 类型安全

· 不需要类型转换

· 可重用代码

泛型确保了编译时的安全性,这允许在编译代码时捕获无效类型。因此,不需要担心运行时异常。不需要单独的类型转换是使用泛型的另一个优点。定义初始类型,然后让代码进行转换。

Java面试重要考点攻克:如何在Java中使用泛型?

图源:unsplash

还可以避免代码重复。如果没有泛型,必须针对不同的类型复制和粘贴相同的代码。使用泛型可以不需要这样做。

好啦,关于Java中泛型的知识都在这里了,要好好掌握呀!

留言点赞关注

我们一起分享AI学习与发展的干货

如转载,请后台留言,遵守转载规范

文章来源:智云一二三科技

文章标题:Java面试重要考点攻克:如何在Java中使用泛型?

文章地址:https://www.zhihuclub.com/196786.shtml

关于作者: 智云科技

热门文章

网站地图