文章目录

  • 泛型的概念
  • 集合中使用泛型
  • 自定义泛型结构
  • 泛型在继承上的体现
  • 通配符的使用


泛型的概念

集合容器类在设计阶段/声明阶段不能确定这个容器实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,JDK1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此把元素的类型设计成一个参数,这个类型参数叫做泛型。Collection<E>ArrayList<E><E>就是类型参数,即泛型。

所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也称为类型实参)。

从JDK1.5以后,Java引入了“参数化类型(Parameterized type)”的概念,允许在创建集合时再指定集合元素的类型,正如:List<String>,这表明该List只能保存字符串类型的对象。JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,从而可以在声明集合变量、创建集合对象时传入类型实参。




集合中使用泛型

Collection中使用泛型:

import java.util.ArrayList;
import java.util.Iterator;/*** @Author: Yeman* @Date: 2021-09-24-15:10* @Description:*/
public class GenericTest {public static void main(String[] args) {//如下在实例化的时候在<>中填入需要的类型即可(不可以是基本数据类型)ArrayList<Integer> list = new ArrayList<>();list.add(99);list.add(0);list.add(121);//遍历方式一for (Integer integer : list){System.out.println(integer);}System.out.println("=====================");//遍历方式二Iterator<Integer> iterator = list.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}
}

Map中使用泛型:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;/*** @Author: Yeman* @Date: 2021-09-24-15:10* @Description:*/
public class GenericTest {public static void main(String[] args) {//如下如下在实例化的时候在<>中填入需要的类型即可(不可以是基本数据类型)// 注意因为Map是键值对,因此需要分别填入“键”和“值”所需要的类型HashMap<String, Integer> map = new HashMap<>();map.put("Jack",26);map.put("Marry",18);map.put("Tom",20);map.put("Lily",22);Set<Map.Entry<String, Integer>> entries = map.entrySet();Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}}
}


自定义泛型结构

1、泛型类、泛型接口

①泛型的声明
interface List<T>{}class GenTest<K,V>{}class student <T extends Person> {}
其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以,常用T表示,是Type的缩写。

②泛型的实例化

List<String> strList = new ArrayList<String>();
Iterator<Customer> iterator = customers.iterator();

<>里面只能是类,不能用基本数据类型填充,可以使用包装类填充。把一个集合中的内容限制为一个特定的数据类型,这就是Generic的核心思想。

泛型类可能有多个参数,此时可将多个参数一起放在尖括号内,如:<E1,E2,E3>

泛型类的构造器与非泛型一样:public GenericClass(){}
public GenericClass<E>(){}是错误的。

泛型不同的引用不能相互赋值:尽管在编译时ArrayList<String>ArrayList<Integer>是两种类型,但是,在运行时只有一个ArrayList被加载到JVM中。

在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法中不能使用类的泛型,因为静态成员是随着类加载而加载的,而类型的指定是在实例化时才确定的。

异常类不能使用泛型。

不能new E[],但是可以E[] elements = (E[])new Object[capacity];

父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型,子类除了指定或保留父类的泛型,还可以增加自己的泛型:

class Father<T1, T2> {}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father<Object,Object>{}
// 2)指定类型
class Son2 extends Father<Integer, String> {}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> {}
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> {}
class Father<T1, T2> {}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son<A, B> extends Father{//等价于class Son extends Father<Object,Object>{}
// 2)具体类型
class Son2<A, B> extends Father<Integer, String> {}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2, A, B> extends Father<T1, T2> {}
// 2)部分保留
class Son4<T2, A, B> extends Father<Integer, T2> {}
class Person<T> {// 使用T类型定义变量private T info;// 使用T类型定义一般方法public T getInfo() {return info;}public void setInfo(T info) {this.info = info;}// 使用T类型定义构造器public Person() {}public Person(T info) {this.info = info;}
}

2、泛型方法

方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。

访问权限 是否为静态 <泛型> 返回类型 方法名(泛型标识 参数名称,...) 异常{//方法体
}
public class Test {public <E> E get(int id, E[] arry) {E result = null;return result;}
}


泛型在继承上的体现

如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<B>并不是G<A>的子类型!比如:String是Object的子类,但是List<String>并不是List<Object>的子类,不能相互赋值。而反过来,如下是可以的:

ArrayList<String> arrayList = new ArrayList<>();
List<String> list = arrayList;



通配符的使用

1、使用

比如:List<?>Map<?,?>
List<?>List<String>List<Object>等各种泛型List的父类。

读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,都包含于Object。而不能向其中添加(写入)对象。除了null,因为它是所有类型的成员:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // 编译时错误
public static void main(String[] args) {List<?> list = null;list = new ArrayList<String>();list = new ArrayList<Double>();list.add(3);//编译不通过,编译时错误list.add(null);List<String> l1 = new ArrayList<String>();List<Integer> l2 = new ArrayList<Integer>();l1.add("AABBCC");l2.add(9);read(l1);read(l2);
}
public static void read(List<?> list) {for (Object o : list) {System.out.println(o);}
}


2、有限制的通配符

①<?>
允许所有泛型的引用调用

②通配符指定上限
extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<=。
<? extends Number> (无穷小 , Number],只允许泛型为Number及Number子类的引用调用。<? extends Comparable>只允许泛型为实现Comparable接口的实现类的引用调用。

③通配符指定下限
下限super:使用时指定的类型不能小于操作的类,即>=。
<? super Number> [Number , 无穷大),只允许泛型为Number及Number父类的引用调用。

Java泛型(1)--集合使用泛型Generic、自定义泛型、泛型在继承上的体现、通配符的使用相关推荐

  1. Java集合之Collection集合、泛型 【集合综合案例:赌神、赌侠、赌神斗地主】

    第一章. Collection集合 1.1 集合概述 集合:集合是java中提供的一种容器,可以用来存储多个数据. 集合和数组既然都是容器,它们有啥区别呢? 数组的长度是固定的.集合的长度是可变的. ...

  2. 【Java】Collection集合和泛型

    学习目标:会存取,掌握特性 学习方式:学习顶层接口/抽象类的共性方法,使用底层的子类创建对象使用 1 集合框架 集合类的继承体系: Collection接口: ·············1) List ...

  3. JAVA day15 Collection(集合)、Iterator迭代器、泛型<E>

    1.Collection(集合) 集合:集合是java中提供的⼀种容器,可以⽤来存储多个数据. 集合与数组的区别: 数组的长度是固定的,集合的长度是可变的. 数组中存储的是同⼀类型的元素,可以存储基本 ...

  4. 01.08学习Java的day18【泛型与集合】

    day18[泛型] 主要内容 泛型 Collection集合 学习目标 能够使用泛型定义类.接口.方法 能够理解泛型上限 能够阐述泛型通配符的作用 能够识别通配符的上下限 能够熟练使用Collecti ...

  5. java 获取泛型t的class_阿里巴巴都鼎力推荐的java基础之集合其他内容和泛型3

    第三节 泛型 3.1为什么需要泛型 没有采用泛型之前 1.不安全:添加元素是无检查 宽进 2.繁琐:获取元素时需要强制类型转换 严出 采用泛型之后 1.安全 严进 2.简单 宽出 3.2什么是泛型ge ...

  6. Java实用教程笔记 泛型与集合框架

    泛型与集合框架 Generics 链表 LinkedList < E >泛型类 接口回调 常用方法 LinkedList< E >泛型类实现Link< E >泛型接 ...

  7. java 泛型 t_Kotlin(2) 泛型与集合

    前言 以一个java老鸟的角度,如何去看 kotlin.Java源代码应该如何用Kotlin重构.如何正确学习kotlin并且应用到实际开发中.本文将会探究. 本文分两大块,重难点和潜规则. 重难点: ...

  8. java set泛型_Java 集合二 泛型、Set相关

    泛型 1.在定义一个类的方法时,因为不确定返回值类型,所以用一个符号代替,这个符号就是泛型 eg:ArrayList list = new ArrayList(); 2.泛型的好处: 1.提高了数据的 ...

  9. 【JAVA SE】第十四章 集合框架、语法糖和泛型

    第十四章 集合框架.语法糖和泛型 文章目录 第十四章 集合框架.语法糖和泛型 一.集合框架 1.概念 2.接口 二.语法糖 1.概念 2.解语法糖 三.泛型 1.概念 2.泛型类 3.泛型接口 4.泛 ...

最新文章

  1. 我的Android进阶之旅------gt;Java全角半角的转换方法
  2. STL---string
  3. c++中的变量作用范围
  4. 设计模式(七)适配器模式(Adapter Pattern)
  5. PS3支持的显示标准介绍
  6. 小米手机,测试时应用图标不能更改,还出现偶尔应用版本还原
  7. android cmake 打印_Android NDK 开发:CMake 使用
  8. 腾讯地图api修改信息窗口样式_ThingJS通过地图的信息窗口展示常见数据
  9. delphi读取xml中的内容property name传递参数_python3 Json和XML数据解析
  10. 12. JavaScript Number 对象
  11. HTML转义字符最全集合
  12. 英语-- such that
  13. 【转】PHP缓存的实现
  14. 解决oracle出现the account is locked问题以及出现not logged on
  15. html分页自动加载数据,硕正控件默认会自动加载数据
  16. 2分钟了解全球智慧城市趋势,解码万亿美元大市场的机遇与格局
  17. 【电商】电商后台设计—购物车
  18. 手机python编程软件 turtle,安卓手机python编程软件
  19. PHP单例模式与常驻内存(总结)
  20. 成都理工大学计算机考研经历,09计算机考研的小小体会~

热门文章

  1. 你好骆驼:自动文件传输
  2. 作为JBoss AS 7模块运行Drools 5.4.0 Final
  3. 使用PowerMock测试对象的内部状态
  4. 如何理解计算机程序中的宏?
  5. java判断手机号_java使用正则表达式判断手机号的方法示例
  6. Path环境变量的理解以及设置MinGW环境变量
  7. etf基金代码大全_银行ETF最新规模首超28亿元再创历史新高,近4个月资金净流入超12亿元...
  8. 轨道运营管理专业自荐书_轨道运营管理专业自荐信x
  9. C 常用新特性(下)
  10. C/C 宏替换详解