java泛型(三)、通配符的使用

本文详细介绍了Java泛型中的通配符概念及其应用场景,包括无限定、上边界限定和下边界限定通配符的使用方法,并通过具体示例说明了如何避免类型检查错误。

通配符有三种:

1、无限定通配符   形式<?>

2、上边界限定通配符 形式< ? extends Number>    //用Number举例

3、下边界限定通配符    形式< ? super Number>    //用Number举例

1、泛型中的?通配符

如果定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据,如果这样写

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
publicclass GernericTest {
    publicstaticvoid main(String[] args) throws Exception{
        List<Integer> listInteger =new ArrayList<Integer>();
        List<String> listString =new ArrayList<String>();
        printCollection(listInteger);
        printCollection(listString);    
    } 
    publicstaticvoid printCollection(Collection<Object> collection){
               for(Object obj:collection){
            System.out.println(obj);
        }  
    }
}

语句printCollection(listInteger);报错

The method printCollection(Collection<Object>) in the type GernericTest is not applicable for the arguments (List<Integer>)

这是因为泛型的参数是不考虑继承关系就直接报错。

这就得用?通配符

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

publicclass GernericTest {
    publicstaticvoid main(String[] args) throws Exception{
        List<Integer> listInteger =new ArrayList<Integer>();
        List<String> listString =new ArrayList<String>();
        printCollection(listInteger);
        printCollection(listString);
    }
    publicstaticvoid printCollection(Collection<?> collection){
               for(Object obj:collection){
            System.out.println(obj);
        }
    }
}


在方法public static void printCollection(Collection<?> collection){}中不能出现与参数类型有关的方法比如collection.add();因为程序调用这个方法的时候传入的参数不知道是什么类型的,但是可以调用与参数类型无关的方法比如collection.size();

总结:使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量的主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。

 

 

2、泛型中的?通配符的扩展

1:界定通配符的上边界

Vector<? extends 类型1> x = new Vector<类型2>();

类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的子类

Vector<? extends Number> x = new Vector<Integer>();//这是正确的

Vector<? extends Number> x = new Vector<String>();//这是错误的

 

2:界定通配符的下边界

Vector<? super 类型1> x = new Vector<类型2>();

类型1指定一个数据类型,那么类型2就只能是类型1或者是类型1的父类

Vector<? super Integer> x = new Vector<Number>();//这是正确的

Vector<? super Integer> x = new Vector<Byte>();//这是错误的

 

提示:限定通配符总是包括自己





### Java 及其通配符的用法 #### 简介 Java 编程语言自 JDK 1.5 起引入了这一特性,允许定义类安全的方法、类和接口而无需指定具体的类参数[^1]。 #### 方法示例 通过使用方法可以在不牺牲类安全性的情况下提高灵活性。当希望某个方法能够处理多种数据类的对象时,可以声明该方法为方法: ```java public class Util { // 定义一个简单的交换函数作为方法的例子 public static <T> void swap(T[] array, int i, int j) { T temp = array[i]; array[i] = array[j]; array[j] = temp; } } ``` 上述代码展示了如何创建接受任意数组并能对其元素进行互换操作的通用工具类 `Util` 中的一个静态成员函数 `swap()` 方法[^3]。 #### 使用通配符增强灵活性 为了进一步提升程序设计中的弹性,在某些场景下可能需要利用通配符来代替具体类参数。例如,如果想要编写既能读取又能写入集合内项目的算法,则应采用上下界限定的方式实现: - **上界通配符** (`<? extends A>`): 表明未知的具体类是给定类的子类; - **下界通配符** (`<? super B>`): 则意味着未知的确切类至少实现了特定父类的功能; 下面是一个展示如何运用这两种形式的操作实例: ```java import java.util.ArrayList; import java.util.List; // 假设有两个接口A,B以及它们各自的实现类C,D,E,F... interface A {} class C implements A {} interface B {} class D implements B {} class E extends Object implements B {} // 下面这个例子说明了如何使用带有限制条件的通配符 void copy(List<? extends Number> sourceList, List<? super Integer> destList){ for (Number element : sourceList) { // 只有当sourceList里的所有元素都可以被转换成Integer的时候才能放入destList中去 if(element instanceof Integer){ destList.add((Integer)element); }else{ System.out.println("Element cannot be cast to Integer"); } } } ArrayList<Integer> integerNumbers = new ArrayList<>(); integerNumbers.add(1);integerNumbers.add(2); ArrayList<Number> numbers = new ArrayList<>(integerNumbers); ArrayList<Object> objects = new ArrayList<>(); copy(numbers,objects); // 正确调用 ``` 此段代码片段解释了如何借助于带有边界约束的通配符完成不同类列表间的安全复制过程[^2]。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值