JAVA 深入理解 泛型通配符

深入理解JAVA 泛型通配符(extends,super)

先解释为什么会用通配符 (非要用通配符不可么?)

class Fruit{}
class Apple extends  Fruit{}
class Jonathan extends Apple{};
class Orange extends  Fruit{};
public class ConvariantArrays {
    public  static  void main(String [] argv){
        Fruit[] fruits = new Apple[10];
        fruits[0]= new Apple();
        fruits[1]= new Jonathan();
        try{
            fruits[0] = new Fruit(); //此处会出现异常  向上类型转换异常
        }catch (Exception ex){
            ex.printStackTrace();
        }
        try{
            fruits[0] = new Orange();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

这种异常出现 会出现在运行期间,通过通配符做标记 可以将这种异常在编译期间就处理完成。

由此可见:通配符不是必须使用的 而是为何方便处理代码而提出的一种纠错机制

在Java中,?代表通配符

通配符的使用方法

1. 在实例化对象的时候, 不确定泛型参数,可以使用通配符进行定义
2. <? extends Object > 代表上边界限定通配符
3.<? super Object > 代表下边界限定通配符

上边界限定通配符 <? extends Object >

  上边界通配符直接只用add()方法受限,但可以用来获取各种数据类型的数据,并赋值非父类的引用
    List<? extends Number > list = null;
    lits  = new ArrayLiat<Integer>();
    list.add(new integer(1));//error 因为不能确定实例化的对象具体类型到时add方法受限
    ...
    list.get();//可以正常使用

下边界限定通配符<? super Object >

下边界通配符使用get()方法受限制(不使用强转),但是可以添加特定类型的值,用于对象写入到一个数据结构里面

List<? super Integet> list = null;
list = new ArrayList<Number>();
list.add();// OK
Number number = list.get(0); //报错 因为List<? super Integer>不知道list存放的对象类型,则使用get获得的值不知晓
package ConvariantArrays;

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

public class NonCovariantGenerics {
    List<Fruit> flsit = new ArrayList<Apple>();  //error  无法实现向上类型的转换
}

package ConvariantArrays;

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

public class GenericWriting {
    static <T> void writExact(List<T> list, T item){ //精确写入
        list.add(item);
        list.add(item);
    }

    static List<Apple> apples = new ArrayList<Apple>();
    static List<Fruit> fruit = new ArrayList<Fruit>();

    static void f1(){
        writExact(apples, new Apple());
        writExact(fruit, new Apple());
    }

    static <T> void  writeWithWildcard(List<? super T> list, T item){ //泛型写入
        list.add(item);
    }

    static void f2(){
        writeWithWildcard(apples, new Apple());
        writeWithWildcard(fruit, new Apple());
    }

    public static void main(String[] args){
        f1();
        f2();
    }
}

package ConvariantArrays;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GenericReading {
    static <T> T ReadExact(List<T> list){//精确读出
       return list.get(0);
    }

    static List<Apple> apples = Arrays.asList(new Apple());
    static List<Fruit> fruit = Arrays.asList(new Fruit());

    static void f1(){
        System.out.println(ReadExact(apples).toString());
        System.out.println(ReadExact(fruit).toString());
    }

    static class Reader<T>{ //封装内部类 进行读出
        T ReadExact(List<T> list){
            return list.get(0);
        }
    }

    static void f2(){
        Reader<Fruit> fruitReader = new Reader<Fruit>();
        Fruit f =  fruitReader.ReadExact(fruit);
        System.out.println(f.toString());
    }

    static class ConvariantReadar<T>{
        T readConvariant(List<? extends T> list){//内部类泛型读出
            return list.get(0);
        }
    }

    static void f3(){
        ConvariantReadar<Fruit> fruitReader = new ConvariantReadar<Fruit>();
        System.out.println(fruitReader.readConvariant(fruit).toString());
        System.out.println(fruitReader.readConvariant(apples).toString());
    }

    public static void main(String [] args){
        f1();
        f2();
        f3();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值