java高级之泛型详解
定义:在java1.5之后推出的。
泛型又叫参数化类型或者类型参数化,在不创建新的类型的情况下,通过泛型指定不同类型来控制形参具体限制的类型,姑且把声明在类上的泛型也叫形参。
泛型应用的意义:
- 在编译期间确认类型,保证编译阶段时的类型不会出错。
- 避免强制转换逻辑。
- 可以提高代码的可重用性和增加程序的灵活性。
注意事项:
泛型的类型擦除:java的泛型只在编译阶段有效,泛型可以在逻辑上分成多种不同的类型,比如List<String> 与 List<Integer> 可以在逻辑上看作是不同的类型,但实质上是同一种类型List,因为java会在编译之后实施去泛型化操作。
证明:
泛型的使用:
- 泛型必须要先声明后才能使用。就像变量似的。
- 泛型采用一对尖括号声明<>。
- 声明一般采用单个大写字母表示,比如 <K,V>等。
- 泛型的声明和使用分为泛型类,泛型接口,泛型方法三种。
泛型类:
定义:声明在类上的泛型。
//泛型参数在类上声明了,可以在类中使用非静态元素使用。
public class TypeDemo<E,V> {public V value;private E element;//这个是错误的,在类上定义的参数不能在静态变量上使用。// 因为静态变量是类级别的,而在类上定义的泛型参数是对象级别的。private static V value2;public E getElement(){return element;}/*** 这个也是错误的,因为静态方法是类级别的,* 而在类上定义的泛型参数是对象级别的。如果要在静态方法中使用泛型,* 可以定义泛型方法。* @return*/public static V getValue(){return null;}}//也可以在继承时使用泛型参数。
public class TypeDemoImpl extends TypeDemo<String,Integer> {
}//也可以在继承时继续声明参数
public class TypeDemoImpl<E,V> extends TypeDemo<E,V> {
}
泛型接口的使用:
例子:List Map<K,V>。
泛型接口与泛型类类似。
public interface TypeInterface<K,V> {K say();V goodBye();
}public class TypeInterfaceImpl implements TypeInterface<String,Integer> {@Overridepublic String say() {return null;}@Overridepublic Integer goodBye() {return null;}
}public class TypeInterfaceImpl<K,V> implements TypeInterface<K,V> {K key;@Overridepublic K say() {return null;}@Overridepublic V goodBye() {return null;}
}
}
泛型方法的使用:
成员方法可以直接使用类上声明的泛型参数,也可以在方法上自己声明泛型参数,但是静态方法要使用泛型就必须自己声明泛型参数。
public class TypeDemo<E,V> {public V value;private E element;//这是使用类上声明的泛型参数Epublic E getElement(){return element;}//这是在成员方法上声明自定义泛型参数Spublic <S> void say(S s){}/*** 这是在静态方法上声明自定义的泛型参数R* @return*/public static <R> R getValue(R role){return role;}public static void main(String[] args) {//使用泛型TypeDemo<String,Integer> stringIntegerTypeDemo = new TypeDemo<>();String element = stringIntegerTypeDemo.getElement();Integer value = stringIntegerTypeDemo.value;stringIntegerTypeDemo.say(true);List<String> strings = TypeDemo.getValue(new ArrayList<>());List<String> strings1 = stringIntegerTypeDemo.getValue(new ArrayList<>());}
}
泛型通配符:
只能在定义方法时的形参使用,限制调用方法时实参的类型。
<?> //无边界,表示调用该方法时传递的实参可以是任意类型。
<? extends E> //上边界,表示调用该方法时传递的实参只能是E类型或者E类型的子类,E可以是真正的类型比如Number,也可以是已经声明好的泛型参数。
<? super E> //下边界,表示调用该方法时传递的实参只能是E类型获取E类型的父类或接口类,E可以是真正的类型比如Number,也可以是已经声明好的泛型参数。
这是Number类继承关系的类图:
public class TongPeiFuDemo<K,V> {//无边界。调用该方法传递的实参可以任意类型的Listpublic void sayHello(List<?> list){}//上边界,调用该方法传递的实参只能是K或者K的子类的Listpublic void sayHelloExtendsK(List<? extends K> list){}//上边界,调用该方法传递的实参只能是Number或者Number的子类的Listpublic void sayHelloKExtendsNumber(List<? extends Number> list){}//下边界,调用该方法传递的实参只能是K或者K的父类或接口的Listpublic void sayHelloSuperK(List<? super K> list){}//下边界,调用该方法传递的实参只能是Number或者Number的父类或接口的Listpublic void sayHelloSuperNumber(List<? super Number> list){}public static void main(String[] args) {TongPeiFuDemo<Number,Object> stringObjectTongPeiFuDemo = new TongPeiFuDemo<>();//测试无边界:多种类型的List都可以。stringObjectTongPeiFuDemo.sayHello(new ArrayList<String>());stringObjectTongPeiFuDemo.sayHello(new ArrayList<Map<String,ObjectList>>());stringObjectTongPeiFuDemo.sayHello(new ArrayList<Integer>());//测试上边界,此时的K泛型参数被赋予了Number类型//因为上边界是number,所以Number型的List可以stringObjectTongPeiFuDemo.sayHelloExtendsK(new ArrayList<Number>());//因为Integer是Number的子类,所以可以stringObjectTongPeiFuDemo.sayHelloExtendsK(new ArrayList<Integer>());//因为String与Number没有继承关系,所以报错stringObjectTongPeiFuDemo.sayHelloExtendsK(new ArrayList<String>());//因为Object是Number的父类,超越了上边界,所以会报错stringObjectTongPeiFuDemo.sayHelloExtendsK(new ArrayList<Object>());//测试下边界//因为下边界是number,所以Number型的List可以stringObjectTongPeiFuDemo.sayHelloSuperNumber(new ArrayList<Number>());//因为Object是Number的父类。处于下边界之上,所以可以。stringObjectTongPeiFuDemo.sayHelloSuperNumber(new ArrayList<Object>());//因为String与Number没有继承关系,所以报错stringObjectTongPeiFuDemo.sayHelloSuperNumber(new ArrayList<String>());//因为Integer是Number的子类,超越了下边界,所以报错stringObjectTongPeiFuDemo.sayHelloSuperNumber(new ArrayList<Integer>());}
}
还可以在类或者接口上限制泛型参数类型,但是不能使用通配符。
public class ClassLimit<E extends Number> {}public interface InterfaceLimit<E extends Number>{}
java高级之泛型详解相关推荐
- 夯实JAVA基本之一 —— 泛型详解(1):基本使用
前言:无论何时,相信自己. 相关文章: 1.<夯实JAVA基本之一 -- 泛型详解(1):基本使用> 2.<夯实JAVA基本之一--泛型详解(2):高级进阶> 3.<夯实 ...
- 【JAVA基础】java基础之-泛型详解
写在前面的话 脑子是个好东西,可惜的是一直没有搞懂脑子的内存删除机制是什么,所以啊,入行多年,零零散散的文章看了无数,却总是学习了很多也忘了很多. 痛定思痛的我决定从今天开始系统的梳理下知识架构,记录 ...
- java高级之注解详解
注解的本质和使用: java中的注解都是继承了Annotation的一个接口. java语言规范规定了注解的定义要用@interface. 注解的作用: a) 注解配合反射可以很好起到了配置文件的作用 ...
- 【Java数据结构】泛型详解+图文,通配符上界、下界
0. 泛型的本质 0. 泛型的目的 1. 泛型的语法 1.1 泛型的使用 2. 包装类 2.1 装箱和拆箱 2.2.1练习题 3 .泛型如何编译 4.泛型的上界 5. 通配符 5.1通配符上界 5.2 ...
- 泛型java 代码讲解_Java泛型详解
2516326-5475e88a458a09e4.png 一,打破砂锅问到底 泛型存在的意义? 泛型类,泛型接口,泛型方法如何定义? 如何限定类型变量? 泛型中使用的约束和局限性有哪些? 泛型类型的继 ...
- Java 泛型详解(超详细的java泛型方法解析)
Java 泛型详解(超详细的java泛型方法解析) 1. 什么是泛型 泛型:是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型.也就是说在泛型使用过程中,操作的数据类型被指定为 ...
- Java泛型详解-史上讲解最详细的,没有之一
目录 1. 概述 2. 一个栗子 3. 特性 4. 泛型的使用 4.1 泛型类 4.2 泛型接口 4.3 泛型通配符 4.4 泛型方法 4.4.1 泛型方法的基本用法 4.4.2 类中的泛型方法 4. ...
- java 泛型详解、Java中的泛型方法、 java泛型详解
本文参考java 泛型详解.Java中的泛型方法. java泛型详解 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用. 什么是泛型?为什么要使用泛型? 泛型,即& ...
- 最详细的java泛型详解
来源:最详细的java泛型详解 对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. ja ...
最新文章
- 【OpenCV】图像代数运算:平均值去噪,减去背景
- php 图片上传预览(转)
- linux c ftp断点续传,求个支持断点续传的ftp脚本
- 美图秀秀 Mac版终于上线 关于美图秀秀 Mac版初体验
- [ASP]没有权限: 'CreateObject'
- mac下 home-brew安装及php,nginx环境安装及配置
- oracle 能被2整除_2021辽宁公务员考试:好用的“整除”法
- codeforce 604B More Cowbell
- 百度网盘提取码_百度网盘无提取码分享方法
- pdf转图片,汉字不显示No glyph for 23495(CID 0969) in font SimSun
- SQLite3介绍及SQL语句详解(SQLite一)
- macOS 安卓模拟器 Nox夜神模拟器 共享目录
- 极限-确定常数使得阶数尽可能为高的无穷小
- CC2530入网流程
- 如何在CentOS 7中设置或更改主机名
- topcoder入门
- C++Test基于CCS的单元测试
- MAC jenkins生成allure报告失败提示:错误:找不到无法加载主类 io.qameta.allure.CommandLine
- css表头固定样式的方法
- 彩色相机与灰度相机的成像原理
热门文章
- Python学习笔记:初探NumPy世界
- 安卓学习笔记41:全球定位系统
- Python学习笔记:演示多根继承
- 《天天数学》连载14:一月十四日
- Python数据分析学习笔记03:NumPy基础(数组与向量化计算)
- java web汽车商城_基于jsp的汽车销售商城系统
- 2017.9.8 无归岛 思考记录
- 2017.3.17 激光炸弹 思考记录
- abb机器人开通选项_ABB机器人623-1Multitasking选项 ABB机器人多任务使用方法教程...
- 矩阵运算和一些基本的几何运算