泛型

作者: 77fb554dbace | 来源:发表于2020-04-24 11:25 被阅读0次

一、为什么要使用泛型?

1. 在编译时进行更强的类型检查。

上例中,指定List只能添加String,当加入非String类型时编译时就会报错。当我们不指定类型时,list默认的类型为Object类型,我们可以同时添加String和Integer两种对象类型,但是当我们取数据时,由于数据类型未知很容易报java.lang.ClassCastException异常。

2.消除类型转换

3.可以实现通用代码逻辑

二、泛型类型

泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?

顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

引入一个类型变量T(其他大写字母都可以,不过常用的就是T,E,K,V等等),并且用<>括起来,并放在类名的后面。泛型类是允许有多个类型变量的。

1.   泛型类

2. 泛型接口

    未传入泛型实参时:

    在new出类的实例时,需要指定具体类型:

2、传入泛型实参

在new出类的实例时,和普通的类没区别。

3.    泛型方法

三、泛型约束和局限

1.不能使用基本类型实例化参数,需要使用基本类型包装类

2.static修饰的静态类和方法不能使用泛型

3.不能创建泛型类数组,但是可以定义

  Generator [] generator;//可以使用

    Generator<String>[] generator = new Generator<String>[3];//不允许

4.不能实例化参数类型

  T data= new T();//不允许

5.不能捕获泛型类异常,但可以throw

6. 无法将Casts或instanceof与参数化类型一起使用。

7. 无法重载每个重载的形式参数类型都擦除为相同原始(raw)类型的方法

    public class Example {

        public void print(Set<String> strSet) { }

        public void print(Set<Integer> intSet) { }//两个方法为同一个参数

    }

四、什么是泛型檫除

        Java语言的泛型采用的是擦除法实现的伪泛型,泛型信息(类型变量、参数化类型)编译之后通通被除掉了。在类型擦除过程中,Java编译器将擦除所有类型参数,如果类型参数是有界的,则将每个参数替换为其第一个边界;如果类型参数是无界的,则将其替换为Object 。

上例中,ArrayList<String>和ArrayList<Integer>是不同的类型,编译后经过泛型檫除,都转为ArrayList<Object>,所以返回为true。

    编译器会进行泛型擦除。

(1)实际上擦除的只是参数和自变量的类型,但会将泛型信息保存到Signature中,我们可以通过匿名类获取。

(2)类结构相关的信息(属性,类,接口,方法签名)即元数据会保存下来,可以通过反射直接获取到的。

五、泛型限制

       使用泛型时,可以使用extends关键字对泛型T进行限制。例如,对数字进行操作的方法可能只希望接受Number 或其子类的实例。

    前面的示例说明了使用带单个限定的类型参数,但是一个类型参数可以具有多个限定。

需要注意:限制是只能继承一个类,并且需要在extends关键字的后面,然后实现多接口

六、通配符?

1.上限统配符<? extends XXX>(只读)

    可以使用上限通配符来放宽对变量的限制, 例如,假设你要编写一种适用于List , List 和List 的方法;可以使用上限通配符来实现。

使用上限通配符,主要用于安全地访问数据,可以访问X及其子类型,并且不能写入非null的数据。

2.下限通配符

下限通配符将未知类型限制为特定类型或该类型的超类型。

使用下限通配符,主要用于安全地写入数据,可以写入X及其子类型。

3.无限定通配符?

表示对类型没有什么限制,可以把?看成所有类型的父类,如Pair< ?>;

比如:

    ArrayList<T>al=new ArrayList<T>(); 指定集合元素只能是T类型

    ArrayList<?>al=new ArrayList<?>();集合元素可以是任意类型,这种没有意义,一般是方法中,只是为了说明用法。

在使用上:

    ?getFirst() : 返回值只能赋给 Object,;

    void setFirst(?) : setFirst 方法不能被调用, 甚至不能用 Object 调用;

参考文档:

官方文档:https://docs.oracle.com/javase/tutorial/java/generics/index.html

中文翻译:https://pingfangx.github.io/java-tutorials/java/generics/types.html

相关文章

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

  • 泛型的使用

    泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法 泛型类 泛型接口 泛型通配符 泛型方法 静态方法与...

  • Java 泛型

    泛型类 例如 泛型接口 例如 泛型通配符 泛型方法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型上下边...

  • 探秘 Java 中的泛型(Generic)

    本文包括:JDK5之前集合对象使用问题泛型的出现泛型应用泛型典型应用自定义泛型——泛型方法自定义泛型——泛型类泛型...

  • Web笔记-基础加强

    泛型高级应用 自定义泛型方法 自定义泛型类 泛型通配符? 泛型的上下限 泛型的定义者和泛型的使用者 泛型的定义者:...

  • 重走安卓进阶路——泛型

    ps.原来的标题 为什么我们需要泛型? 泛型类、泛型接口和泛型方法(泛型类和泛型接口的定义与泛型方法辨析); 如何...

  • Kotlin泛型的高级特性(六)

    泛型的高级特性1、泛型实化2、泛型协变3、泛型逆变 泛型实化 在Java中(JDK1.5之后),泛型功能是通过泛型...

  • Java 19-5.1泛型

    泛型类定义泛型类可以规定传入对象 泛型类 和泛型方法 泛型接口 如果实现类也无法确定泛型 可以在继承类中确定泛型:

  • 【Swift】泛型常见使用

    1、Swift泛型4种 泛型函数泛型类型泛型协议泛型约束 2、泛型约束3种 继承约束:泛型类型 必须 是某个类的子...

网友评论

      本文标题:泛型

      本文链接:https://www.haomeiwen.com/subject/zcbksftx.html