当前位置:   article > 正文

【入门基础】java泛型和通配符详解

【入门基础】java泛型和通配符详解

【入门基础】java泛型和通配符详解

前言

Java泛型(Generics)是JDK 5中引入的一个新特性,它提供了编译时类型安全检测机制,允许程序员在编译时检测到非法的类型。泛型的主要目的是在编译期间对类型进行检查,使得类型错误能在编译时而不是运行时被捕获,从而提高程序的稳定性和安全性。同时,它也消除了类型转换的代码,使得代码更加简洁和易于维护。

泛型类

泛型类是在类定义时,类名后面加上一对尖括号<>,尖括号中放置类型参数(type parameters)。例如:

java
复制代码
public class Box<T> {  
    private T t;  
  
    public void set(T t) { this.t = t; }  
    public T get() { return t; }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里的T就是一个类型参数,它指定了Box类内部将使用哪种类型的数据。在创建Box类的实例时,可以指定具体的类型,例如Box。

泛型方法

泛型方法不仅能在类级别定义类型参数,还能在方法级别定义。泛型方法允许在调用方法时指定类型参数。例如:

java
复制代码
public class Util {  
    public static <T> T getFirst(T[] inputArray) {  
        if (inputArray.length == 0) {  
            throw new IllegalArgumentException("Array is empty");  
        }  
        return inputArray[0];  
    }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里定义了一个类型参数T,它表示该方法将返回一个与数组类型相同的对象。

泛型接口

泛型接口与泛型类类似,接口名后面也可以定义类型参数。例如:

java
复制代码
public interface Pair<K, V> {  
    public K getKey();  
    public V getValue();  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里<K, V>定义了两个类型参数K和V,分别代表键值对的键和值的类型。

通配符(Wildcards)

通配符?用于泛型中,表示未知的类型。它主要有三种用法:

  • 无界通配符(Unbounded Wildcards):使用?表示未知的类型,例如List<?>可以表示任何类型的List。
  • 上界通配符(Upper Bounded Wildcards):使用? extends T表示未知的类型,但它是T或T的子类。例如List<? extends Number>可以表示List或List等。
  • 下界通配符(Lower Bounded Wildcards):使用? super T表示未知的类型,但它是T或T的父类。例如List<? super Integer>可以表示List或List等。

使用场景

  • 无界通配符:常用于需要读取但不需要写入集合的场景,因为它保证了类型安全但限制了向集合添加元素。
  • 上界通配符:常用于需要从集合中读取元素的场景,并且你知道这些元素至少是某个类型的实例。
  • 下界通配符:常用于需要向集合中添加元素的场景,并且你添加的元素类型是这个集合中元素类型的父类型。

非主流用法

  • 泛型数组:虽然在Java中不能直接创建泛型数组(如T[] array = new T[10];是编译错误的),但可以通过反射(Array.newInstance)或泛型方法的类型参数来间接创建泛型数组。这种用法不常见,因为需要处理额外的复杂性和性能开销。
  • 泛型枚举:Java允许在枚举中使用泛型。虽然枚举通常用于表示一组固定的常量,但泛型枚举可以提供额外的灵活性,例如允许枚举值持有不同类型的对象。这种用法较为特殊,但在需要枚举与类型关联时非常有用。
  • 泛型异常:Java泛型不能用于throws子句中声明的异常类型,因为异常处理是在运行时进行的,而泛型信息在编译时就被擦除了。然而,可以通过泛型方法或泛型类来封装异常处理逻辑,以提供类型安全的异常处理。这种用法虽然不是直接对异常类型使用泛型,但实现了类似的效果。
  • 混合使用上下界通配符:
    虽然在实际编程中不常见,但可以混合使用上界(? extends T)和下界(? super T)通配符来创建复杂的类型约束。这种用法通常用于需要同时满足读取和写入操作,且对类型有严格要求的场景。然而,由于这种用法较为复杂且易出错,因此不是主流用法。
  • 在泛型类/接口声明中使用通配符:
    虽然在类/接口声明中直接使用通配符(如class MyClass<? extends T> {…})是不合法的,但可以在类/接口内部的方法或字段中使用通配符来提供额外的灵活性。这种用法虽然不常见,但在设计复杂的泛型API时可能会用到。
  • 利用通配符实现多态性:
    通配符提供了一种在泛型代码中实现多态性的方式。虽然这不是通配符独有的特性(泛型本身就是为了提供类型安全的多态性),但通配符的灵活性使得在某些情况下可以更加优雅地实现多态性。例如,使用List<?>作为方法参数可以接受任何类型的List,从而提供更大的灵活性。

总结

需要注意的是,上述非主流用法并非推荐的做法,它们可能增加代码的复杂性和出错的风险。在大多数情况下,应优先考虑使用泛型和通配符的主流用法来编写清晰、简洁、易于维护的代码。同时,随着Java语言的发展和新特性的引入,一些曾经看似非主流的用法可能会逐渐变得主流或过时。因此,建议始终关注Java语言的最新动态和最佳实践。在这里插入图片描述

我是杰叔叔,一名沪漂的码农,下期再会!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/860607
推荐阅读
相关标签
  

闽ICP备14008679号