• 泛型(3)-类型通配符


        正如前面讲的,当使用一个泛型类时(包括声明变量和创建对象两种情况),都应该为这个泛型类传入一个类型实参,如果没有传入类型实际参数,编译器就会提出泛型警告,结社现在需要定义一个方法,该方法里有一个集合形参,集合形参的元素类型时不确定的,那么该怎么定义呢?

    import java.util.ArrayList;
    import java.util.List;
    public class Demo1 {
    public void test(List<Object> list){
    for (int i=0;i<list.size();i++){
    System.out.println(list.get(i));
    }
    }
    public static void main(String[] args) {
    //创建一个Demo1对象
    Demo1 demo1=new Demo1();
    //创建一个list集合
    List<String>list=new ArrayList<>();
    demo1.test(list);//编译错误
    }
    }

    上面程序编译错误,表明List<String>并不能被当成List<Object>对象使用,也就是说List<String>并不是List<Object>的子类
    String是Object的一个子类型(子类或者子接口),List是具有泛型声明的类或者接口,然而List<String>却并不是List<Object>的子类型!这一点非常值得注意,与大部分人的习惯认知不同
    Java泛型的设计原则是,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException异常.
    数组和泛型的不同之处:
    假设Foo是Bar的一个子类型(子类或者子接口),那么Foo[]也是Bar[]的子类型,但G<Foo>并不是G<Bar>的子类型(子类或者接口).Foo[]自动向上转型为Bar[],方式称之为型变.
    代码如下:
    Integer [] ia=new Integer[5];bei
    Number [] na=ia;
    na[0]=0.5;//编译不报错,运行时引发ArrayStoreException异常.


    =============================================================================================================================================
    使用类型通配符
      为了表示各种泛型List的父类,可以使用类型通配符,类型通配符是一个'?',将一个问号作为类型实参传给List集合,写作:List<?>(意思是元素类型未知的List).这个问号(?)被称为通配符,它的元素类型可以匹配任何类型,
    可以将上面的代码修改如下
    public void test(List<?> list){
    for(int i=0;i<list.size();i++){
    system.out.print(list.get(i))
    }}
    现在使用任何类型的List来调用它,程序依然可以访问集合list中的元素,其类型是Object,永远是安全的,因为不管List的真实类型是什么,它包含的都是Object,除了List<?>,这种写法还适用于任何支持泛型声明的接口和类.
    如Set<?>,Collection<?>,Map<?,?>等.
    package com.j1803.Type_wildcards;

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

    public class Demo1 {

    public void test(List<?> list){
    for (int i=0;i<list.size();i++){
    System.out.println(list.get(i));
    }
    }

    public static void main(String[] args) {
    //创建一个Demo1对象
    Demo1 demo1=new Demo1();
    //创建一个list集合
    List<String>list=new ArrayList<>();
    demo1.test(list);//编译错误

    List<Integer>list1=new ArrayList<>();
    list1.add(1);
    list1.add(2);
    list1.add(3);
    demo1.test(list1);
    }
    }
    answer:
    1
    2
    3

    但这种带有通配符的List仅表示它是各种泛型List的父类,并不能把元素放入其中.例如,下面代码进会引起编译错误.
    List<?> c=new ArrayList<>();
    c.add(new Object());//出现编译错误
    原因是程序无法确定c集合中元素的类型,所以不能向其中添加对象.




     
  • 相关阅读:
    Generator函数介绍
    C语言基础三
    C语言基础二
    C语言基础一
    node——路由控制
    Node.js_HTTP模块
    node_Express安装及检验
    conda Pyhon版本切换
    JAVA泛型里面各值代表的意义
    jq实现表格多行列复制
  • 原文地址:https://www.cnblogs.com/shadow-shine/p/9656004.html
Copyright © 2020-2023  润新知