一、泛型介绍:
JDK5除了推出foreach新循环,还推出了一个新特性:泛型
泛型作用:在一个类或接口的声明处指定该类中某个属性的类型。或声明方法返回值的类型或方法参数的类型
- 泛型也称为参数化类型。 它允许我们在一个类或接口的声明处指定该类中某个属性的类型或
方法返回值的类型或方法参数的类型,使得我们使用这个类时更方便更灵活。
- 使用了泛型的类叫泛型类、 使用了泛型的接口叫泛型接口、 使用了泛型的方法叫泛型方法
泛型在集合中广泛使用,用于指定该集合中的元素类型。
注意:当没有指定泛型时,默认类型为Object类型。
用泛型的好处: 避免了类型强转的麻烦, 在编译期就做了类型检查,避免了在运行时出现ClassCastException。
注意: 泛型具体的类型不能为8种基本类型(可以为8种包装类型)
注意:泛型只在编译阶段有效(检查数据类型)正确检验泛型后,编译后会将泛型的相关信息擦除。
上述结论可通过下面反射的例子来印证: (因为绕过了编译阶段也就绕过了泛型,输出结果为:[zyq, 100])
二、泛型用在集合中:
三、泛型用在类上
- 泛型类可以用于:规定成员变量的类型, 方法参数类型 , 返回值类型
- 在定义类时使用了泛型, 需要在创建对象的时候确定泛型:
- (jdk1.7后右边的泛型可以省略<第二个泛型括号内容可以省略new对象时第二个泛型具体的类型>)
泛型在定义的时候不具体,使用的时候才变得具体。在使用的时候确定泛型的具体数据类型。
- 案例:
四、泛型方法:
- 使用泛型方法声明的类型 : 方法参数类型 , 返回值类型
- 案例:
五、泛型接口
- 接口在定义时可以使用泛型
- 实现一个使用了泛型接口 : 需要在子类定义处声明类型, 或者在对象创建时声明类型
案例:
六、泛型通配符:
泛型通配符:不知道使用什么类型来接收的时候,此时可以使用?, ?表示未知通配符。
集合中使用 ? 作为泛型时不能添加元素(只能从集合中取元素)(所以集合基本不用?)
七、泛型高级用法:
- 泛型高级用法: 用?规定一个泛型的上限和下限。
1.泛型的上限:
格式: 类型名称 <? extends 类Cls > 对象名称
意义: 只能接收Cls类型及其子类型 (?是Cls的子类型, 或者?和Cls类型相同)
当从一个结构中读取已知是某类型或某类型的子类型时,适合用泛型的上限来规定数据(泛型的上限适合读)。
2.泛型的下限:
式:类型名称 <? super 类Cls > 对象名称
解释:?是Cls的父类型(或者?和Cls类型相同) (规定了子类型为Cls,父类型无上限<没规定父类型>)
意义: 只能接收该类型及其父类型
比如: < T super Integer > 这个泛型中的T表示: T只能是Integer的父类。
当向一个结构中存入已知是某类型或某类型的父类型时,适合用泛型的下限来规定数据(因为读取时的元素类型不确定,只是知道读取的元素类型是Cls的父类型)(泛型的下限适合写)。
案例:
八、泛型擦除:
简单理解:在编译期间,所有的泛型信息都会被擦除掉。例如代码中定义的List<Object>和List<String>等类型,在编译后都会变成List。JVM看到的只是List,JVM虚拟机运行字节码文件时是不能获取用泛型规定的类型信息的。
泛型的擦除原则,特别是在Java中,指的是在编译时泛型类型参数会被替换或“擦除”为其上限类型或Object类型,以便在运行时能够正确地执行代码。以下是关于Java泛型擦除原则的详细解释:
1.所有参数化容器类都被擦除成非参数化的(raw type):
例如,List<E>、List<List<E>>等参数化的容器类在编译后都会被擦除成非参数化的List。
2.所有参数化数组都被擦除成非参数化的数组:
例如,List<E>[]这样的参数化数组会被擦除成List[]。
3.Raw type的容器类,被擦除成其自身:
如果一个容器类本身就是raw type(非参数化的),那么它会被擦除成它自身。例如,List(raw type)在擦除后仍然是List。 List<泛型>编译后会成为List
4.原生类型(int, String以及它们的包装类)都擦除成他们的自身:
原生类型在Java中不是泛型类型,因此它们不会被擦除。它们保持原样。
例如: Integer n1;编译后还是Integer n1; String s编译后还是String s
5.参数类型E,如果没有上限,则被擦除成Object:
在Java中,如果没有明确指定泛型参数的上限(例如,List<T>中的T),那么它会被默认擦除成Object。
6.所有约束参数如<? extends E>、<X extends E>都被擦除成E:
对于有约束的泛型参数,如List<? extends Number>,在擦除时会被处理为其约束的上限类型Number。
7.如果有多个约束,擦除成第一个:
对于多个约束的情况,如List<T extends Serializable & Cloneable>,泛型参数T会被擦除成第一个约束类型Serializable。
8.擦除导致强制类型转换变为自动和隐式的:
由于泛型擦除,在运行时所有的泛型类型信息都丢失了。因此,在使用泛型集合时,如果要将元素放入集合或从集合中取出元素,可能需要进行强制类型转换。但由于擦除机制,这些转换在Java中通常是自动和隐式的。
9.类型通配符和上限限定符用于编译时类型检查:
为了在编译时捕获类型错误,Java提供了类型通配符(如?)和上限限定符(如extends)。这些工具可以帮助程序员在编译阶段就进行类型检查,从而避免在运行时出现ClassCastException等异常。
这些擦除原则是Java泛型机制的基础,理解它们对于正确编写和使用泛型代码至关重要。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!