民工心事 发表于 2024-6-15 03:56:48

Java泛型通配符深度解析:无限定、上界、下界通配符全面把握

粉丝福利:微信搜刮「万猫学社」,关注后回复「电子书」,免费获取12本Java必读技能册本。
泛型通配符的简介

泛型通配符如同一个无形的手,操控着步伐的行进方向,让步伐的逻辑更加严密,更加安全。
泛型通配符,顾名思义,它是泛型的一种特殊情势,用于表现各种类型的泛型。你可能会问,为什么我们需要它呢?其实,当我们在开辟过程中,经常会遇到一种情况,就是我们无法确定一个聚集的具体类型,大概我们需要表现任何类型的情况,这时候,泛型通配符就派上了用场。
它的出现,不光让我们的代码更加机动,而且也让我们的步伐更加结实。在接下来的内容中,我们将会深入探讨泛型通配符的各种情势,包括无限定通配符、上界通配符和下界通配符。
无限定通配符

在我们了解了泛型通配符的根本概念后,让我们深入研究一下Java中的无限定通配符。无限定通配符,也就是我们经常看到的<?>。它的出现,就像是一扇窗户,让我们的视野变得更加开阔。
https://img-blog.csdnimg.cn/direct/a183b371244649a0b148addaa0b1484b.jpeg#pic_center
在现实的开辟中,它资助我们处理各种不确定的类型,让我们的代码在面对复杂的类型问题时,变得更加机动。
那么,什么时候我们需要用到无限定通配符呢?当我们需要处理的对象类型不确定,大概我们只关心对象的某种共性,而不关心对象的具体类型时,这时候,无限定通配符就派上了用场。
下面,让我们通过一段代码来看一下如何利用无限定通配符。
import java.util.Arrays;
import java.util.List;

public class UnboundedWildcard {
    // 使用无限定通配符的方法
    public static void printList(List<?> list) {
      for (Object item : list) {
            System.out.println(item);
      }
    }

    public static void main(String[] args) {
      List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
      List<String> stringList = Arrays.asList("One", "More");
      
      // 无论是Integer列表还是String列表,都可以被这个方法处理
      printList(integerList);
      printList(stringList);
    }
}
在这段代码中,我们定义了一个printList方法,这个方法接收一个参数,这个参数的类型是List<?>。这个List<?>就是我们所说的无限定通配符,它表现这个列表可以接收任何类型的对象。在方法内部,我们利用了增强型for循环来遍历这个列表,并打印出每个元素。无论是Integer列表还是String列表,都可以被这个方法处理,这就是无限定通配符的魔力所在。
在我们明确了无限定通配符的用法后,让我们进一步探讨Java中的上界通配符。
上界通配符

在我们把握了无限定通配符的利用之后,接下来我们将深入探讨Java中泛型通配符的另一个重要概念——上界通配符。上界通配符是一种特殊的泛型通配符,它通过关键字extends来限定泛型的类型范围。这种上界通配符的利用场景主要是当我们需要利用的对象具有某种共同的超类时,这样可以保证我们在处理这些对象时,可以调用到这些共同超类中的方法。
让我们通过一个实例来更好地明确上界通配符的利用。假设我们有一个Animal类和它的两个子类Dog和Cat,我们需要写一个方法来处理这些动物的列表,但是我们希望这个方法可以或许担当任何Animal的子类的列表,这时我们就可以利用上界通配符。
class Animal {
    public void eat() {
      System.out.println("Animal is eating...");
    }
}

class Dog extends Animal { }

class Cat extends Animal { }

public class Test {
    public static void feedAnimals(List<? extends Animal> animals) {
      for (Animal animal : animals) {
            animal.eat();
      }
    }

    public static void main(String[] args) {
      List<Dog> dogs = Arrays.asList(new Dog(), new Dog());
      List<Cat> cats = Arrays.asList(new Cat(), new Cat());

      feedAnimals(dogs);
      feedAnimals(cats);
    }
}
上述代码中,我们定义了一个方法feedAnimals,它担当一个Animal的子类的列表作为参数,我们利用了上界通配符<? extends Animal>来限定这个列表的类型。然后在这个方法中,我们可以调用Animal类中定义的eat方法,因为我们知道这个列表中的所有对象都至少是Animal类型的。这就是上界通配符的威力,它允许我们在保持代码的机动性的同时,也能保证类型的安全。
明确了上界通配符的利用,我们接下来将探讨另一种泛型通配符——下界通配符。
下界通配符

在我们探讨了上界通配符之后,现在我们来看一看下界通配符。下界通配符用关键字super表现,它意味着你可以利用泛型类的父类来更换泛型。换句话说,如果你有一个类A,你可以利用任何A的父类来更换A。这样的话,你就可以确保你的代码对所有的父类都是兼容的,而不光仅是A类。
下界通配符的一个常见利用场景是在你需要写入数据的时候。因为你知道你可以安全地写入一个父类的对象,所以你可以利用下界通配符。这样的话,你可以写入A类,也可以写入A的任何父类,这就大大增加了你的代码的机动性。
让我们通过一个简朴的例子来看一下如何利用下界通配符。假设我们有一个Animal类和一个Dog类,Dog类是Animal类的子类。我们另有一个List,我们想要在这个List中添加一些动物。
class Animal {
    public void eat() {
      System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    @Override
    public void eat() {
      System.out.println("Dog is eating");
    }
}

public class OneMoreClass {
    public static void main(String[] args) {
      List<? super Animal> animals = new ArrayList<>();
      animals.add(new Animal());
      animals.add(new Dog());
      for (Object animal : animals) {
            ((Animal) animal).eat();
      }
    }
}
在这个例子中,我们定义了一个List,这个List的类型是? super Animal。这意味着我们可以在这个List中添加Animal,也可以添加Animal的任何子类,比方Dog。然后我们遍历这个List,并调用每个动物的eat方法。注意,因为我们利用了下界通配符,所以我们需要欺压类型转换。
这就是下界通配符的根本用法。通过利用下界通配符,我们可以写出更加机动、更加通用的代码。
总结

颠末这一系列的学习,我们对Java中的泛型通配符有了更深入的明确。泛型通配符,无论是无限定通配符、上界通配符还是下界通配符,都在我们开辟的过程中起着重要的作用。它们就像是我们手中的工具,资助我们更好地操控代码,处理各种类型问题,让我们的步伐更加结实,更加机动。
无限定通配符,让我们在面对类型不确定的情况下,依然可以或许机动应对。上界通配符,让我们在处理具有共同超类的对象时,可以或许调用到超类中的方法,保证了类型的安全。下界通配符,让我们在需要写入数据时,可以或许写入一个父类的对象,增加了代码的机动性。
然而,我们也需要注意,泛型通配符并不是万能的,它也有其局限性。在利用泛型通配符时,我们需要清晰地知道我们要处理的是什么类型的对象,需要调用什么方法,这样才能更好地利用泛型通配符,写出更加高效、更加结实的代码。
   粉丝福利:微信搜刮「万猫学社」,关注后回复「电子书」,免费获取12本Java必读技能册本。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Java泛型通配符深度解析:无限定、上界、下界通配符全面把握