延伸 -- 泛型 -- 通配符的使用

通配符有三种:

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

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

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

1、泛型中的?通配符

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

package limeGenericity.genericityPrescribe;

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

public class Test03 {

    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<Integer>();
        List<String> strList = new ArrayList<String>();
        printCollection(intList);
        printCollection(strList);
    }

    private static void printCollection(Collection<Object> collection) {
        for(Object coll : collection){
            System.out.println(coll);
        }
    }
}

Console : 

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    The method printCollection(Collection<Object>) in the type Test03 is not applicable for the arguments (List<Integer>)
    The method printCollection(Collection<Object>) in the type Test03 is not applicable for the arguments (List<String>)

    at limeGenericity.genericityPrescribe.Test03.main(Test03.java:12)

语句printCollection(listInteger);报错

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

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

这就得用?通配符

 

package limeGenericity.genericityPrescribe;

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

public class Test03 {

    public static void main(String[] args) {
        List<Integer> intList = new ArrayList<Integer>();
        List<String> strList = new ArrayList<String>();
        printCollection(intList);
        printCollection(strList);
    }

    private static void printCollection(Collection<?> collection) {
        for(Object coll : collection){
            System.out.println(coll);
        }
    }
}

在方法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的(Generics)是一种在编译期进行类检查的机制,它允许在定义类、接口和方法时使用参数,从而实现类安全的编程。主要目的是提高代码的重用性、可读性和类安全性,避免运行时的类转换错误。 ### 1. 的基本语法 通过尖括号 `<T>` 来声明类参数,其中 `T` 是一个占位符,表示某种类(Type)。常见的类参数命名习惯有: - `T`:Type(类- `E`:Element(元素) - `K`:Key(键) - `V`:Value(值) - `N`:Number(数值) #### 示例:类 ```java public class Box<T> { private T value; public void setValue(T value) { this.value = value; } public T getValue() { return value; } } ``` #### 使用类 ```java Box<String> stringBox = new Box<>(); stringBox.setValue("Hello"); String str = stringBox.getValue(); // 无需强制类转换 Box<Integer> intBox = new Box<>(); intBox.setValue(123); Integer num = intBox.getValue(); ``` ### 2. 方法 也可以用于方法中,使得方法可以接受任意类的参数。 ```java public class Util { public static <T> void printArray(T[] array) { for (T item : array) { System.out.println(item); } } } // 调用方法 String[] names = {"Alice", "Bob", "Charlie"}; Util.printArray(names); Integer[] numbers = {1, 2, 3}; Util.printArray(numbers); ``` ### 3. 接口 接口也可以定义。 ```java public interface Comparable<T> { int compareTo(T other); } public class Person implements Comparable<Person> { private String name; public Person(String name) { this.name = name; } @Override public int compareTo(Person other) { return this.name.compareTo(other.name); } } ``` ### 4. 类擦除(Type Erasure) Java的是通过**类擦除**实现的,这意味着信息只在编译期存在,在运行时会被擦除为原始类(Object 或指定的上界类)。 例如: ```java List<String> list1 = new ArrayList<>(); List<Integer> list2 = new ArrayList<>(); ``` 在运行时,`list1` 和 `list2` 的实际类都是 `ArrayList`,信息被擦除了。这是为了兼容 Java 5 之前的版本。 ### 5. 的好处 - **类安全**:在编译期就能发现类错误,避免 `ClassCastException`。 - **减少强制类转换**:无需手动进行 `(String)` 这样的类转换。 - **代码复用**:一套逻辑可以处理多种数据类。 ### 6. 通配符(Wildcard) 支持通配符 `?`,用于表示未知类- `<?>`:任意类 - `<? extends T>`:上界通配符,表示 `T` 或其子类 - `<? super T>`:下界通配符,表示 `T` 或其父类 ```java public static void printList(List<? extends Number> list) { for (Number n : list) { System.out.println(n.doubleValue()); } } ``` --- ### 常见面试问题延伸
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值