type
status
date
slug
summary
tags
category
password
icon

泛型类型的创建

泛型类的创建

泛型接口的创建

泛型作⽤⼩结

  1. 帮助检查代码中的类型,提前报错;
  1. ⾃动强制转型。

「创建⼀个泛型类型」到底是为了什么?

  • 本质⽬标或原因:这个类型的不同实例的具体类型可能会有不同,针对的是实例
  • 因此,静态字段和静态⽅法不能使⽤泛型类型的类型参数(也就是那个 T

继承

 

类型参数 <T> 到底是什么

  • 不是⼀个类,也不是⼀个接⼝。只是⼀个标记符号,⼀个代号
  • 代什么?代表这个类型内部某个通⽤的类型

多个类型参数

泛型类型的实例化

  • 其实就是「确定这个 T 的实际值」的意思

泛型类型实例化

上界

<? extends Xxx>
用处

下界

<? super Xxx>
用处?
java 的范型存在类型擦出
💡
数组有这个问题吗?
没有 为什么? 因为数组没有「类型擦除」 类型擦除是怎么回事?——后⾯有专⻔的⼀节课讲。

泛型⽅法和类型推断

怎么写

声明
调用:
利⽤类型推断删除尖括号后:

泛型⽅法的实例化

泛型⽅法也有实例化哟,因为泛型⽅法也可以把类型参数的类型进⾏确定。 具体呢?每⼀次泛型⽅法的调⽤就是⼀次对这个泛型⽅法的实例化。 例如上⾯的例⼦,就是把 E 的类型确定为了 Tv

静态泛型⽅法

泛型的本质:我到底什么时候要使⽤泛型

泛型的意义

  • 泛型的意义在于:泛型的创建者让泛型的使⽤者可以在使⽤时(实例化时) 细化类型信息,从⽽可以触及到「使⽤者所细化的⼦类」的 API。 或者,泛型是「有远⻅的创造者」创造的「⽅便使⽤者」的⼯具。
    • 所以泛型参数可以是⼀个⽅法的返回值类型:
      • 也可以是放在⼀个接⼝的参数⾥,等着实现类去写出不同的实现

      延伸⽤途

      • 不过,泛型由于语法⾃身特性,所以也有⼀个延伸⽤途:类型约束。
         

        情景再归纳

        Type Parameter 和 Type Argument

        • Type Parameter:
          • public class Shop<T> ⾥⾯的那个 <T> ;
            • 表示「我要创建⼀个 Shop 类,它的内部会⽤到⼀个统⼀的类型,这 个类型姑且称他为 T 」。
        • Type Argument:
          • 其它地⽅尖括号⾥的全是 Type Argument,⽐如 Shop<Apple> appleShop; 的 Apple ;
          • 表示「那个统⼀代号,在这⾥的类型我决定是这个」。
        • Type ParameterType Argument ;泛型的创建和泛型的实例化
         

        T 情景归纳

        • 写在类名(接⼝名)右边的括号⾥,表示 Type Parameter 的声明,「我要创建⼀个代号」;
        • 写在类或接⼝⾥的其他地⽅,表示「这个类型就是我那个代号的类型」;
          • 很容易搞错的场景:当继承或实现⼀个泛型类型的时候,如果⽗类(或⽗接 ⼝)名的右边也写了 <T> :
            • 这个右边⽗类(接⼝)右边的 <T> 表示:
            • 我要对⽗类(接⼝)进⾏实例化,即确定它类型参数的实际值
            • 实例化的具体类型是我的这个类型参数
              • 所以它从⽗类和⾃⼰这两个不同⻆度来看,同时具有「已确定的实例化」和「未确定的声明」这两个属性。
          • 使⽤⾃⼰的类型参数(Type Parameter)来作为
        • 只在这个类或者接⼝⾥有⽤,出了类或接⼝就没⽤了(对于泛型⽅法是,只在这 个⽅法⾥有⽤,出了这个⽅法就没⽤了)。
          • 所以不能这么写:
            • 也不能这么写:

            ? 号情景归纳

            • 只能写在泛型实例化的地⽅:
              • 表示「这个类型是什么都⾏,只要不超出 ? extends 或者 ? super 的限 制」。
            • 虽然⽤于实例化,但因为它表示「类型还有待进⼀步确定」,它不能⽤在类型参 数最终确定的时候:
              • 「类型还有待进⼀步确定」的特殊场景:嵌套泛型实例化:
                • 包在多层尖括号⾥⾯的实例化,因为全都属于「类型有待进⼀步确定」, 所以全都可以加问号。

              extends 情景归纳

              • ⽤在泛型类型或泛型⽅法声明的时候,对类型参数设置上界
              • ⽤在泛型实例化时 ? 号可以出现的地⽅,⽤来设置上界,缩⼩ ? 号的限制范 围。

              super 情景归纳

              • 只有⼀个地⽅:⽤在泛型实例化时 ? 号可以出现的地⽅,⽤来设置下界,缩⼩ ? 号的限制范围。
               

              泛型中的「重复」和「嵌套」

              <T> 的重复:

              表示对⽗类(⽗接⼝)的扩展。

              类名的重复:

              同样表示对⽗类(⽗接⼝)的扩展(囧)

              正常的实例化嵌套:

              这个不⽤多解释。

              类型参数的上界是⼀个泛型类型:

              有⼈在这⾥会有点晕,但其实只要分开看: HenCoderList<T> 是⼀个东⻄; Shop<Apple> 是另⼀个东⻄。要完全分开分析。
              同理,就算再复杂⼀点:
              也是⼀样的分开分析就好了。

              极端案例:Enum

              • extends Enum<E> 表示⼀个上界,即「 E 需要是 Enum<E> 的⼦类」
              • 这是个 Comparable<E> 的实现,所以 compareTo(E o) 的参数就需要是 个 Enum<E> 的⼦类
                • 进⼀步:这个类也是⼀个 Enum<E> ,所以表示「你必须和跟⾃⼰⼀样的 类作⽐较」
              • Enum 这个类还有⼀个 getDecalaringClass() ⽅法:
                • 所以这个⽅法的返回值也需要是⼀个 Enum<E> 的⼦类。
              💡
              获取参数和返回值中的泛型

              泛型中的类型擦除和「不可以」以及突破 「不可以」

              • 运⾏时,所有的 T 以及尖括号⾥的东⻄都会被擦除
              • ListList<String> 以及 List<Integer> 都是⼀个类型;
              • 但是所有代码中声明的变量或参数或类或接⼝,在运⾏时可以通过反射获取到泛 型信息;
              • 但但是,运⾏时创建的对象,在运⾏时通过反射也获取不到泛型信息(因为 class ⽂件⾥⾯没有);
              • 但但但是,有个绕弯的⽅法就是创建⼀个⼦类(哪怕⽤匿名类也⾏),⽤这个⼦ 类来⽣成对象,这样由于⼦类在 class ⽂件⾥就有,所以可以通过反射拿到运⾏
              • 时创建的对象的泛型信息。 ⽐如 Gson 的 TypeToken 就是这么⼲的。

              Kotlin 的泛型

              • 场景跟 Java ⼀样,不过⽤法有⼀点不⼀样;
              • Java 的 <? extends> 在 Kotlin ⾥写作 <out> ;Java 的 <? super> 在Kotlin ⾥写作 <in>
              • 另外,Kotlin 还增加了 out T in T 的修饰,来在类或接⼝的声明处就限制使⽤,这样你在使⽤时就不必再每次都写;
              • Kotlin 的 * 号相当于 Java 的 ? 号,基本⼀样,只是有些细节不⼀样
               
              LeakCanary 原理解析注解 Annotation Processing
              Loading...
              shuouyang
              shuouyang
              android开发 ReactNative开发 小程序开发
              最新发布
              AOSP 环境搭建
              2025-3-29
              View 绘制流程-源码解析
              2025-3-12
              HTTP
              2025-3-4
              JVM 虚拟机
              2025-2-28
              蓝牙-BLE-基础
              2025-2-28
              从 OkHttp 的原理来看 HTTP
              2025-2-19
              公告
              🎉热点信息🎉
              --- 1 ---
              Jet Brains 推出新的跨平台支持 Kotlin MultiPlatform
              --- 2 ---
              新的小巧便捷的依赖注入框架 Koin
              --- 3 ---
              新一代 API 查询语言 GraphQL