泛型通配符和泛型的使用总结

泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

 

泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符.

  此时只能接受数据,不能往该集合中存储数据。

泛型的通配符:

  ?:代表任意的数据类型

使用方式:
  不能创建对象使用

  只能作为方法的参数使用

复制代码
public static void main(String[] args) {
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);

        ArrayList<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");

        printArray(integers);
        printArray(list);

        /*
              错误写法
              ArrayList<?> objects = new ArrayList<?>();
         */
    }
    /*
          定义一个方法,能遍历所有类型的ArrayList集合
          这时候我们不知道ArrayList集合使用什么数据类型,可以泛型的通配符 ? 来接受数据类型
          注意:
              泛型没有继承概念的
       */
    public static void printArray(ArrayList<?> list){
        //使用迭代器遍历集合
        Iterator<?> iterator = list.iterator();
        while (iterator.hasNext()){
            //iterator.next()方法,取出的元素是Object,可以接受任意的数据类型
            Object next = iterator.next();
            System.out.println(next);
        }

    }
复制代码
复制代码
public static void main(String[] args){
    //可以存储整数的集合
    Collection<Integer> list01 = new ArrayList<Integer>();
    //此时list01可以存储整数的数据
    //展示list01集合当中的数据
    getElement(list01);
    //可以存储String字符串集合
    Collection<String> list02 = new ArrayList<String>();
    //此时list02可以存储字符串的数据
    //getElement(list02);//如果方法的接受的行参类型的集合的泛型是Object,那么这么写是错误的  Collection<Object>    x    不可以的
    //此时如果换成泛型通配符?就可以接收
    getElement(list02);//可以
}
/*public static void getElement(Collection<Object> coll){
    
}*/
public static void getElement(Collection<?> coll){
    //只能接收Integer类型的数据
    //此时?可以代表任意类型
}
复制代码

 

 

通配符高级使用----受限泛型

之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。

泛型的上限:

  格式:类型名称<extends类〉对象名称

  意义︰只能接收该类型及其子类

泛型的下限:

  格式︰类型名称〈?super类〉对象名称

  意义︰只能接收该类型及其父类型

泛型的上限限定:? extends E代表使用的泛型只能是E类型的子类/本身

泛型的下限限定:? super E代表使用的泛型只能是E类型的父类/本身

复制代码
public static void main(String[] args) {
        Collection<Integer> list1 = new ArrayList<Integer>();
        Collection<String> list2 = new ArrayList<String>();
        Collection<Number> list3 = new ArrayList<Number>();
        Collection<Object> list4 = new ArrayList<Object>();
        getElement1 (list1);
      //  getElement1(list2);//报错
        getElement1(list3);
      // getElement1(list4);//报错


      // getElement2(list1);//报错
      // getElement2(list2);//报错
        getElement2(list3);
        getElement2(list4);

        /*
                类与类之间的继承关系
                Integer extends Number extends Object
                String extends object
         */
    }
   //泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
    public static void getElement1(Collection<? extends Number> coll){}
    //泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
    public static void getElement2(Collection<? super Number> coll){}
复制代码

上限通配符

复制代码
//现已知Object类、String类、Number类、Integer类,其中Number是Integer的父类。
public static void main(String[] args){
 
    //通配符"?"在创建泛型类对象时限制泛型类的类型
    Collection<? extends Number> list1 = null; 
    list1 = new ArrayList<Integer>(); //Integer类是Number类型的子类
    //list1 = new ArrayList<String>(); //报错,String类不是Number类型或Number类型的子类
 
    Collection<String> list2 = new ArrayList<String>();
    Collection<Number> list3 = new ArrayList<Number>();
    Collection<Object> list4 = new ArrayList<Object>();
 
    //可以将由通配符限制的泛型类对象用在方法的参数中以防传入不允许接收的类型对象
    getElement(list1); //Integer类是Number类型的子类
    getElement(list2); //报错,String类不是Number类型或Number类型的子类
    getElement(list3); //是Number类型
    getElement(list4); //报错,Object类是所有类的默认父类
}
 
//泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement(Collection<? extends Number> coll){}
复制代码

下限通配符

复制代码
//现已知Object类、String类、Number类、Integer类,其中Number是Integer的父类。
public static void main(String[] args){
 
    //通配符"?"在创建泛型类对象时限制泛型类的类型
    Collection<? super Number> list1 = null; 
    //list1 = new ArrayList<Integer>(); //报错,Integer类不是Number类型的父类
    //list1 = new ArrayList<String>(); //报错,String类不是Number类型或Number类型的父类
    list1 = new ArrayList<Object>();
 
    Collection<String> list2 = new ArrayList<String>();
    Collection<Number> list3 = new ArrayList<Number>();
 
    //可以将由通配符限制的泛型类对象用在方法的参数中以防传入不允许接收的类型对象
    getElement(list1); //Object类是所有类的默认父类
    getElement(list2); //报错,String类不是Number类型或Number类型的父类
    getElement(list3); //是Number类型
}
 
//泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement(Collection<? super Number> coll){}​
复制代码

 

泛型的使用总结

泛型的使用

1.泛型类和泛型方法

复制代码
/*
class 类型名<泛型标识,泛型标识, ...>{
    private 泛型标示 变量名;
}
*/
public class GenericDemo<T> {
    private T key;

    public GenericDemo(T key) {
        this.key = key;
    }

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }

    public static void main(String[] args) {
        
        /*
        类名<具体的数据类型> 对象名 = new 类目<具体的数据类型>();

        JDK1.7后,可以省略成这样:
        类名<具体的数据类型> 对象名 = new 类目<>();
        */
        GenericDemo<Integer> integerGenericDemo = new GenericDemo<>(10);
        GenericDemo<String> stringGenericDemo = new GenericDemo<>("abc");
        //如果没有指定具体的数据类型,此时,操作类型是Object
        GenericDemo genericDemo = new GenericDemo("genericDemo");

        System.out.println(integerGenericDemo.key);
        System.out.println(stringGenericDemo.key);
        System.out.println(genericDemo.key);
        //泛型类型在逻辑上可以看成是多个不同的类型,但实际上是相同类型
      System.out.println(integerGenericDemo.getClass()==stringGenericDemo.getClass());    //输出结果为true
    }
}
复制代码

 


⒉泛型接口和泛型方法

语法

修饰符 <T,E,...> 返回值类型 方法名(形参列表){
    方法体... 
}

 

public interface GeneratorInterface<T> {
  public T next();
}

public class FruitGenerator<T> implements GeneratorInterface<T> {

    @Override
    public T next() {
        return null;
    }
}
复制代码
public class VegetablesGenerator implements GeneratorInterface<String> {

    private String[] vegetables = new String[]{"Potato", "Tomato"};

    @Override
    public String next() {
        Random rand = new Random();
        return vegetables[rand.nextInt(2)];
    }
}
复制代码

 

3.泛型通配符

复制代码
package demo02;

import java.util.ArrayList;
import java.util.Iterator;

/*
  泛型的通配符:
      ?代表任意的数据类型
  使用方式:
          不能创建对象使用
          只能作为方法的参数使用
*/
public class demo02Generic {
    public static void main(String[] args) {
        ArrayList<Integer> list1=new ArrayList<>();
        list1.add(1);
        list1.add(2);

        ArrayList<String> list2=new ArrayList<>();
        list2.add("哈哈");
        list2.add("嗯嗯");
        printArray(list1);
        printArray(list2);

    }
    /*
       定义一个方法,能遍历所有类型的ArrayList集合
       这时候我们不知道ArrayList集合使用什么数据类型,可以泛型的通配符
       ?来接受数据类型
       注意:
          泛型没有继承概念
    */
    public  static void printArray(ArrayList<?> list){
        //使用迭代器遍历集合
        Iterator<?> it=list.iterator();
        while(it.hasNext()){
            //it.next()方法,取出的元素是Object,可以接收任意的数据类型
            Object i=it.next();
            System.out.println(i);

        }

    }
}
复制代码

高级的泛型通配符--受限泛型

复制代码
package demo02;

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

public class Demo03Generic {
    public static void main(String[] args) {
        Collection<Integer> list1=new ArrayList<Integer>();
        Collection<String> list2=new ArrayList<String>();
        Collection<Number> list3=new ArrayList<Number>();
        Collection<Object> list4=new ArrayList<Object>();

        getElement(list1);
        getElement(list2);//报错
        getElement(list3);
        getElement(list4);//报错

        getElement2(list1);//报错
        getElement2(list2);//报错
        getElement2(list3);
        getElement2(list4);

        /*
          类与类之间的继承关系
          Integer extends Number extends Object
          String extends Object
        */

    }
    //泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
    public  static  void getElement(Collection<? extends  Number> coll) {
    }
    //泛型的下限:此时的泛型?,必须是Number类型或者Number的父类
    public  static void getElement2(Collection<? super  Number> coll){}
}
复制代码

 

posted @   漁夫  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示