精华内容
下载资源
问答
  • 泛型通配符

    2021-08-26 15:39:15
    文章目录泛型通配符通配符高级使用--受限泛型 泛型通配符 如上图所示,print方法下就确定泛型类型的话,不是很方便,无法打印其他泛型类型的集合元素,因此,需要用到泛型通配符------"?"。若改成 public static ...

    泛型通配符

    在这里插入图片描述
    如上图所示,print方法下就确定泛型类型的话,不是很方便,无法打印其他泛型类型的集合元素,因此,需要用到泛型通配符------"?"。若改成 public static void print(ArrayList<?> list),则不会出现上述问题。
    在这里插入图片描述
    注意:1.在定义集合泛型的时候不能用通配符,会报错,它只用于接收数据!
    2.另外,泛型没有继承的概念,所以不能用object来接收数据。
    3. 如果使用迭代器来遍历输出元素,在用next方法接收的时候用object来定义变量名。

    在这里插入图片描述
    2.
    在这里插入图片描述
    3.

    在这里插入图片描述

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

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

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

    已知Java中:

    1. Integer extends Number extends Object

    Integer是Number的子类是Object的子类

    1. String extends Object
      String是Object的子类

      观察下面代码及报错:

    public class Demo06Generic {
        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){}
    }
    
    
    展开全文
  • java基础-泛型通配符

    2021-03-12 14:38:42
    java基础-泛型通配符
  • 主要介绍了Java中泛型通配符的使用方法,结合实例形式分析了java中泛型通配符的功能、语法及在泛型类创建泛型对象中的使用方法,需要的朋友可以参考下
  • 泛型&泛型通配符

    2021-09-09 15:13:41
    泛型通配符: 数据结构 增强for循环: 泛型: 可以在类,接口,方法中使用,就是一种未知的数据类型,在使用的时候确定其具体数据类型 表达式: <泛型变量> 泛型变量可以是任意字母,一般写E 泛型的好处: 将...

    目录

    泛型:

    泛型的好处:

    泛型通配符:

    数据结构

    增强for循环:


    泛型:

            可以在类,接口,方法中使用,就是一种未知的数据类型,在使用的时候确定其具体数据类型

            表达式: <泛型变量>  泛型变量可以是任意字母,一般写E

    泛型的好处:

            将运行时期的ClassCastException,转移到了编译时期变成了编译失败 ,避免了类型转换的麻烦  

    1. 集合不使用泛型

            可能会发生类型转换异常 , 避免类型转换异常,就需要先做类型判断,再转型--->比较麻烦

    2. 集合使用泛型

            指定泛型的具体数据类型只能是引用数据类型

    3. 定义含有泛型的类:

            格式:public class 类名<泛型变量>{   }

            创建含有泛型的类的对象的时候,指定泛型的具体数据类型(只能是引用数据类型)

    4. 定义含有泛型的接口:

            格式: public interfa 接口名<泛型变量>{ }

            public class 类名<泛型变量> implements 接口名<泛型变量>{}

            <  >尖括号里面填字母表示不指定数据类型,在定义变量是在确定数据类型

    5. 定义含有泛型的方法:

            格式: 修饰符<泛型变量> 返回值类型 方法名(形参列名){ 方法体 }

            调用含有泛型方法的时候,确定泛型的具体数据类型

    泛型通配符:

            用 ? 表示

            格式:数据类型 <?> 变量

            使用场景:如果想要使变量在未来接收有泛型定义的对象,又不确定泛型要定义的类型可以使用泛型通配符

    注意:

            如果使用了泛型通配符,那么该集合变量元素类型默认是Object类型

            如果使用了泛型通配符,那么该集合变量只能取元素,无法增删元素

            泛型本身不存在继承关系,不可以给已指定的变量接收其他泛型类型的对象

    通配符的高级使用:

            受限泛型

                    上限 : 

                            格式: <? extends 类名>

                            表示只结束泛型是该类类型或者该类的子类类型

                    下限:

                            格式: <? super 类名>

                            表示只接受泛型是该类类型或者该类的父类类型

    数据结构

            栈结构:先进后出

            队列结构:先进先出

            数组; 查询快,增删慢

            链表: 查询慢,增删快

            二叉查找树: 提高搜索效率

    增强for循环:

            专门用来遍历数组和Collection集合

            原理: 内部基于Iterator迭代器实现,所以在遍历过程中不能对集合的元素进行增删操作,否则会报错

            格式: for(数据类型 变量名 : 数组名\集合名){ }

    展开全文
  • Java泛型 通配符 通配符有三种使用方式 上限通配符 - ? extends扩展类型。 下限通配符 - ? super超级类型。 无限通配符 - ?...上限通配符 - 如果变量属于类别,请使用带有通配符的extends关键字。...//Java 泛型通配符 p

    Java泛型 通配符

    通配符有三种使用方式

    • 上限通配符 - ? extends扩展类型。
    • 下限通配符 - ? super超级类型。
    • 无限通配符 - ?

    通配符关键字

    • 上限通配符 - 如果变量属于类别,请使用带有通配符的extends关键字。
    • 下限通配符 - 如果一个变量是外部类别,请使用带有通配符的super关键字。
    • 无限通配符 - 如果可以使用Object类方法访问变量,则使用未绑定的通配符。
    • 无通配符 - 如果代码访问进/出类别中的变量,那么不要使用通配符。

    示例:

    //Java 泛型通配符
    public class GenericWildcard {
        //上限通配符
        public static void deleteCat(List<? extends Cat> catList, Cat cat) {
            catList.remove(cat);
            System.out.println("Cat Removed");
        }
    
        //下限通配符
        public static void addCat(List<? super RedCat> catList) {
            catList.add(new RedCat("Red Cat"));
            System.out.println("Cat Added");
        }
    
        // 无限通配符
        public static void printAll(List<?> list) {
            for (Object item : list)
                System.out.println(item + " ");
        }
    
        public static void main(String[] args) {
    
            List<Animal> animalList = new ArrayList<Animal>();
            List<RedCat> redCatList = new ArrayList<RedCat>();
            addCat(animalList);
    
            addCat(redCatList);
            addCat(redCatList);
    
            printAll(animalList);
            printAll(redCatList);
    
            Cat cat = redCatList.get(0);
            deleteCat(redCatList, cat);
            printAll(redCatList);
        }
    }
    
    class Animal {
        String name;
    
        Animal(String name) {
            this.name = name;
        }
    
        public String toString() {
            return name;
        }
    }
    
    class Cat extends Animal {
        Cat(String name) {
            super(name);
        }
    }
    
    class RedCat extends Cat {
        RedCat(String name) {
            super(name);
        }
    }
    
    class Dog extends Animal {
        Dog(String name) {
            super(name);
        }
    }
    
    展开全文
  • List<String> list1 = new ArrayList<>() List<Object> list2 = new ArrayList<>() list1 = list2//编译错误 List<?> list = null; list = list1; list = list2;
  • 详细介绍了Java中的泛型的概念、原理和使用,比如上、下限泛型、泛型通配符等。

    详细介绍了Java中的泛型的概念、原理和使用,比如上、下限泛型、泛型通配符等。

    1 泛型

    诞生的必要性:Java1.4或更早版本,原来List集合当中可以存放任何类型,当对集合当中的元素进行统一操作的时候,容易引发ClassCastException异常。当存在各种数据类型的时候,不利于对集合的元素进行统一操作。

    解决思路:像数组一样,只能存放某种数据类型。

    此时在JDK1.5 添加了一个新技术:泛型。

    1.1 定义

    泛型,即“参数化类型”。顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型变量),然后在使用/调用时传入具体的类型(类型实参)。这种类型变量可以用在类、接口和方法的创建中。当然最常见的就是用在集合中。

    设定的语法:类名<类型变量> ,也叫参数化类型。

    类型变量:使用大写的形式,只能是引用类型,不能使基本数据类型。Java中,用变量E表示集合的元素类型,K和V分别表示表的key与value类型,T表示“任意类型”。

    用具体的类型替换类型变量就可以实例化泛型类型。

    1.2 作用

    1. 将运行时期的异常提前到了编译时异常(classcastexception),方便了元素的统一操,优化了程序结构。
    2. 泛型参数一旦确定,就规定了在类使用的时候,只能存放某一种数据类型。此时集合还能够记住集内元素的类型,从而无需对集合元素进行强制转换,使得程序更加简洁。

    1.3 泛型类

    把泛型定义在类上。格式:public class 类名<泛型类型1,…>

    注意:泛型类型必须是引用类型。

    案例

    在类上声明了一个不确定的类型(类型变量);在该类当中都可以使用该不确定的类型。

    public class Genericity<T> {
        private T obj;
    
        public T getObj() {
            return obj;
        }
    
        public void setObj(T obj) {
            this.obj = obj;
        }
    }
    

    使用泛型类

    Genericity<String> tool = new Genericity<String>();
    //使用String对T进行初始化。
    tool.setObj("ggg");  
    

    1.4 泛型方法

    泛型可以定义在方法上:泛型方法。泛型声明在方法的返回值之前,并且可以与类名上的泛型声明不一致!

    class ss<Q> {
    
        /**
         * 泛型方法,使用自己的泛型T
         *
         * @param t   T
         * @param <T> 新类型<T>的声明
         */
        public <T> void set(T t) {
    
        }
    
        /**
         * 泛型方法,使用类上的泛型Q
         *
         * @param q Q
         * @return Q 返回值的类型
         */
        public Q getXxx(Q q) {
            return q;
        }
    }
    

    注意:

    当在类名之后声明了泛型时。如果想在该类静态方法使用和类一样的泛型变量,即使在类上已经声明了泛型,还是要像自定义泛型方法一样,类下面的静态方法的返回之前一定还要重新声明一次。但是非静态方法就能直接使用同名泛型变量,不用再次声明!案例如下:

    public class GenericDemo01<T> {
    
        //普通方法使用与类同名泛型,不需要声明
        //传递T类型参数,直接使用
        public void get1(T t)
        {
    
        }
        //返回T类型,可以直接使用
        public T get2()
        {
            return null;
        }
    
        //静态方法使用同名泛型,和自定义泛型方法一样,必须声明
        //想要返回T类型或传递T类型的参数,则必须在返回之前重新声明
        public static <T> void get3(T t)
        {
    
        }
        //想要返回T类型或传递T类型的参数,则必须在返回之前重新声明
        public static <T> T get4()
        {
            return null;
        }
    }
    

    使用细节

    List list=New ArrayList();

    List list=New ArrayList();

    List list=New ArrayList(); //泛型推断.JDK1.7

    以上三种写法都可以。但是前后声明的泛型类型必须要相同.泛型只能存放引用类型,在JDK1.5之后建议使用泛型,否则会报警告。

    1.5 泛型接口

    1.5.1 泛型接口的定义

    需求: 对学生进行增删改查操作:

      interface StudentDao{
        //增加:
         void add(Student stu);
         //删除:
         boolean delete(String id);
         //修改:
         boolean update(Student stu);
         //查询: 唯一性查询:
         Student findById(String id);
      }
    

    设定一个具体的实现类: 对接口当中的方法进行具体的实现,那么针对一个对象就需要设定一套接口,并且设定一套实现类:

    Teacher : 设定一套接口, 设定一套实现类:
    Person : 设定一套接口, 设定一套实现类:

    这样就比较麻烦了,因此可以使用泛型接口。

    1.5.1 泛型在接口上的使用

    使用泛型接口可以减少Dao接口的设计数量。

      interface Dao<T>{
        void add(T t);//增加
    	
    	boolean delete(String id); //删除
    	
    	boolean update(T t);
    	
    	T findById(String id);
      } 
    

    1.6 泛型通配符以及上、下限泛型

    Collection<?> ?:可以代表任意类型

    Collection<?> c5 = new ArrayList<Object>();
    Collection<?> c6 = new ArrayList<Animal>();
    Collection<?> c7 = new ArrayList<Dog>();
    Collection<?> c8 = new ArrayList<Cat>();
    

    1.6.1 上限泛型

    Collection<? extends E> ? 只能是E类型 或者是E 类型的子类(否则编译报错):这样的泛型称之受限泛型:上限泛型。

    一般在存储元素时使用上限(? extends E)。因为一旦确定好类型,存入的就都是E或E的子类,取出时都按照上限类型E来运算,不会出现类型安全隐患

    Collection<? extends Animal> c9 = new ArrayList<Object>();
    Collection<? extends Animal> c10 = new ArrayList<Animal>();
    Collection<? extends Animal> c11 = new ArrayList<Dog>();
    Collection<? extends Animal> c12 = new ArrayList<Cat>();
    

    1.6.1 下限泛型

    Comparator<? super E> ? 只能是E类型或者是E类型的父类型(否则编译报错):受限泛型的下限泛型。(一般只有比较器用到)

            //min比较器
            min(Collection<? extends T> coll, Comparator<? super T> comp)
            //sort排序比较器
            sort(List<T> list, Comparator<? super T> c)
                    
            Collection<? super Animal> c13 = new ArrayList<Object>();
            Collection<? super Animal> c14 = new ArrayList<Animal>();
            Collection<? super Animal> c15 = new ArrayList<Dog>();
            Collection<? super Animal> c16 = new ArrayList<Cat>();
    

    1.7泛型擦除

    Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。如在代码中定义的List和List等类型,在编译之后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。这样做的目的,是确保能和Java 5之前的版本开发二进制类库进行兼容。

    类型擦除的基本过程也比较简单,首先是找到用来替换类型参数的具体类。这个具体类一般是Object。如果指定了类型参数的上界的话,则使用这个上界。把代码中的类型参数都替换成具体的类。

    ArrayList<String> list1 = new ArrayList<String>();
    list1.add("abc");
    ArrayList<Integer> list2 = new ArrayList<Integer>();
    list2.add(123);
    //将返回true
    System.out.println(list1.getClass() == list2.getClass());
    
    展开全文
  • Java中泛型通配符的使用.pdf
  • Java泛型:使用泛型、泛型应用、自定义泛型、泛型继承、泛型通配符
  • 泛型通配符

    2020-03-05 11:26:24
    在看Java核心技术卷I中泛型通配符相关的知识时产生了很多疑问,通过了解后简单的做下笔记方便回顾。 本文重点记录了一下这几个问题: 为什么要用泛型通配符? ? extends T为什么只能调用使用了泛型取出对象的成员...
  • 泛型类、泛型方法、泛型接口、泛型通配符

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 28,798
精华内容 11,519
关键字:

泛型通配符