泛型

概念:是一个未知的数据类型,是一个参数化类型

使用场景:

  • 如果需要给一个类型定义属性,但是这个类型中的属性不确定,可以使用泛型来代替定义。
  • 如果需要定义一个方法,但是该方法的参数列表类型和返回值类型不确定,可以使用泛型来定义。

泛型类 的定义与使用

在定义类型时,类上有泛型的使用,那么该类就是泛型类

格式:

class 类名<泛型>{  } class person<T>{private T name;}

注意事项:

  • 如果想要在类中使用泛型,首先需要在类的声明上,声明该泛型符号

  • 如何定义泛型:

    • 泛型符号可以是任意标识符
    • 但是一般使用大写的字母来表示 M T Q L
  • 如果一个类型定义了泛型,在使用这个类型的时候,可以确定泛型也可以不确定泛型

    • 如果不确定泛型的话:默认使用Object来接收参数

    • 如果确定了泛型:那么就只能使用确定的类型来接收参数

  • 在确定泛型的时候,泛型前后要一致

  • 后面的泛型类型可以不写,因为可以根据泛型推断,将后面的类型会默认和前面保持一致。但是<>不能省略。

  • 可以在一个类中使用多个不同的泛型,使用几种就需要声明几种

  • 在使用类型时,如果类型声明了多个泛型,要么一个都不指定,要么全都指定

好处:可以提高类型的扩展性

代码:

public void main(String[] args) {person p = new person();p.name = 180.2;p.age = "453";person<String, Integer> p1 = new person<>();p1.name = "chen";p1.age = 11;person<Double,Boolean> p2 = new person<>();p2.name = 18.5;p2.age = true;}class person<T,M>{T name;M age;}

泛型方法 的定义和使用

使用泛型定义的方法

格式:

修饰符 <泛型的声明> 返回值类型 方法名(){} 

注意事项:

  • 如果定义了一个静态方法,该静态方法中需要使用泛型,那么静态方法只能自己先声明,后使用。不能使用类上声明的泛型。
public void main(String[] args) {        printValue("chen");printValue(124);     //默认转换成Integer类型、只能是引用类型}//定义了一个静态方法,必须先声明泛型public static <T> void printValue(T t){System.out.println(t);}
  • 如果定义了一个非静态方法,该方法既可以使用类上声明的泛型,也可以自己声明泛型。
public class E <L>{public void main(String[] args) {E e = new E();e.printValue1(11);}
//可以在类上声明
public void printValue1(L l){System.out.println(l);}
//也可以自己声明
public <L> void printValue1(L l){System.out.println(l);}
  • 方法中如果需要声明泛型,也可以同时声明多个泛型
public void main(String[] args) {printValue2("chen",22);}public static <P,M> void printValue2(P t,M m){System.out.println(t);System.out.println(m);}

泛型接口 的定义和使用

概述:如果接口中的抽象方法需要使用泛型,也需要先在接口上声明该泛型

注意:

  • 将来接口的实现类如果实现了接口,但是没有指定泛型类型,在实现类中默认使用Object来表示该泛型。
//接口中应用泛型
public interface A <T,M>{public T get();public void set(M m);
}
//实现类实现该接口
public class elemA implements A{@Overridepublic Object get() {    //默认Object类型return null;}@Overridepublic void set(Object o) {}
}
  • 实现类实现接口之后,如果需要使用该泛型,就要在实现接口时,就要指定该泛型的类型,指定的类型是谁, 就使用谁。
//接口中应用泛型
public interface A <T,M>{public T get();public void set(M m);
}
//实现类实现该接口
public class elemA implements A<String,Integer>{@Overridepublic String get() {return null;}@Overridepublic void set(Integer integer) {}
}
  • 如果实现类实现接口之后,没有指定泛型,也需要使用这个泛型符号,只能在实现类中也声明该泛型。
//接口中应用泛型
public interface A <T,M>{public T get();public void set(M m);
}
//实现类实现该接口,泛型不指定,需要在类名后声明
public class elemA <T,M> implements A<T,M>{@Overridepublic T get() {return null;}@Overridepublic void set(M m) {}
}

泛型 集合对泛型的使用

概述:学习的集合是支持泛型的

​ 可以使用泛型,也可以不使用泛型

如果定义集合之后,没有使用泛型:元素在集合中都是Object接收

如果定义集合之后,使用了泛型,元素在集合中就是定义的类型

public class Arraylist_E <T> {ArrayList<T> a = new ArrayList<>();
}

泛型定义集合的特点

  • 如果定义的集合使用了泛型,那么当前集合中只能添加对应类型的元素;
  • 使用集合元素特有的方法时,不需要向下转型,直接使用即可

集合遍历的总结

  • 使用迭代器或者增强for循环遍历集合时,因为集合制定了确切的泛型类型,所以在使用集合的元素时不需要再向下转型
 //增强for循环遍历for (String o:a){System.out.println(o);  //不用向下转型}//迭代器遍历ListIterator<String> it = a.listIterator();while (it.hasNext()){String s =it.next();      //不用向下转型System.out.println(s);}
  • 使用转数组:toArray方法遍历的时候,该方法的返回值固定是Object类型

    所以使用元素的特殊方法时,也需要向下转型。

  • 但是转数组,有另外一种方式:toArray(T[] arr)

    在转数组的时候,可以自主准备一个数组,用来存储元素,数组可以和数据的类 型保持一致,那么在转换之后也不需要向下转型。

    • 如果准备的数组空间正好够存,或者空间多余元素,那么可以转移到自己的数组中。
    • 如果准备的数组空间不够存储元素,该方法会返回一个新数组用来存储数据。
//转数组遍历String[] strs = new String[a.size()];for (int i = 0; i < strs.length; i++) {String s = strs[i];System.out.println(s);}

泛型 的通配符

概述:将来定义数据类型时,如果这个数据类型不确定,可以使用泛型来表示这个不确 定的类型;也可以使用泛型通配符来定义这个不确定的类型。

分类:

  • ?:泛型的通配符 可以表示任何泛型
  public static void main(String[] args) {ArrayList<Object> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();ArrayList<Number> list3 = new ArrayList<>();ArrayList<String> list4 = new ArrayList<>();getList1(list1);getList1(list2);getList1(list3);getList1(list4); public static void getList1(ArrayList<?> list){}
//都可以
  • ? extends E: 泛型通配符 可以表示泛型E类型或者泛型E类型子类类型
  public static void main(String[] args) {ArrayList<Object> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();ArrayList<Number> list3 = new ArrayList<>();ArrayList<String> list4 = new ArrayList<>();getList2(list1);   //Object   不行getList2(list2);   //Integer  可以getList2(list3);   //Number   可以getList2(list4);   //String   不行//? extends Number:表示可以接收Number类型或者Number子类类型public static void getList2(ArrayList<? extends Number> list){}
  • ? super E: 泛型通配符 可以表示泛型E类型或者泛型E类型的父类类型
  public static void main(String[] args) {ArrayList<Object> list1 = new ArrayList<>();ArrayList<Integer> list2 = new ArrayList<>();ArrayList<Number> list3 = new ArrayList<>();ArrayList<String> list4 = new ArrayList<>();getList3(list1);    //Object  可以getList3(list2);    //Integer 不行getList3(list3);    //Number  可以getList3(list4);    //String  不行//? super Number:表示可以接收Number类型或者Number父类类型public static void getList3(ArrayList<? super Number> list){}

Java中对泛型的理解及应用相关推荐

  1. Java中的泛型 --- Java 编程思想

    前言 ​ 我一直都认为泛型是程序语言设计中一个非常基础,重要的概念,Java 中的泛型到底是怎么样的,为什么会有泛型,泛型怎么发展出来的.通透理解泛型是学好基础里面中非常重要的.于是,我对<Ja ...

  2. java定义list_我的Java Web之路59 - Java中的泛型

    本系列文章旨在记录和总结自己在Java Web开发之路上的知识点.经验.问题和思考,希望能帮助更多(Java)码农和想成为(Java)码农的人. 目录 介绍 再谈Java中的类型 为什么需要泛型? J ...

  3. [转载] 详解Java中的泛型

    参考链接: Java中具有泛型的有界类型 1.什么是泛型 泛型,即"参数化类型".一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名 ...

  4. java如何用反射把具体方法抽象_如何在Java 中使用泛型或反射机制对DAO进行抽象...

    如何在Java 中使用泛型或反射机制对DAO进行抽象 发布时间:2020-11-26 16:07:42 来源:亿速云 阅读:80 作者:Leah 本篇文章为大家展示了如何在Java 中使用泛型或反射机 ...

  5. Java中的泛型全解析(一)

    为什么我们需要泛型? 通过两段代码我们就可以知道为何我们需要泛型 实际开发中,经常有数值类型求和的需求,例如实现int类型的加法, 有时候还需要实现long类型的求和, 如果还需要double类型的求 ...

  6. Java中Map集合如何理解(四)——精简

    目录 引言 概念 Map集合实现类 HashMap LinkedHashMap TreeMap 默认排序 自定义排序方式 常用API 遍历Map集合 键找值 键值对 Lambda表达式 结束语 引言 ...

  7. Java 中的泛型(两万字超全详解)

    文章目录 前言 一.泛型概述 1. 什么是泛型?为什么要使用泛型? 2. 泛型使用场景 3. 泛型概述小结 二.泛型类 1. 泛型类的定义 2. 泛型类的使用 三.泛型接口 四.泛型方法 1. 泛型方 ...

  8. Java中创建泛型数组

    Java中创建泛型数组 使用泛型时,我想很多人肯定尝试过如下的代码,去创建一个泛型数组 T[] array = new T[]; 当我们写出这样的代码时编译器会报Cannot create a gen ...

  9. 【笔记】JAVA中的泛型和反射

    泛型 Java的泛型是如何工作的?什么是类型擦除? ----泛型是通过类型擦除来实现的,编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息.例如List在运行时仅用一个Lis ...

最新文章

  1. ajax中的url如何传递变量_如何创建和参数化UDT数据类型中的变量及IN,OUT 等参数?...
  2. 重启redis命令_redis系列之——数据持久化(RDB和AOF)
  3. 卸载注册表_系统小技巧:软件卸载不了?这里办法多
  4. No fallback instance of type class found for feign client user-service(转)
  5. python中的异或操作_Python中的异或和位操作的反转
  6. mysql having的用法
  7. 去除eclipse打开后不断update的问题
  8. mysql ibd文件还原_MySQL
  9. c语言寻找文件指令,c语言实现文件查找
  10. 基于Android幼儿园管理系统,幼儿园管理系统
  11. 01.J2EE开发环境搭建
  12. 2021最新阿里代码规范(前端篇)
  13. 一文带你看透手机号码归属地
  14. Adobe Photoshop CC2014 安装过程
  15. Win7/10/11:去除、恢复软件图标小箭头
  16. 电脑远程桌面连接怎么操作?
  17. contents()与children()的用法和区别
  18. 0.96寸OLED屏使用详解
  19. Python课程设计项目-基于机器学习的糖尿病风险预警分析系统
  20. 腾讯php开发工程师面试题

热门文章

  1. 哺乳期哪些事不能做?
  2. com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:Unrecognized field
  3. MySQL tips
  4. 天龙八部天外服务器不响应,有生命的服务器 天龙八部3智能天外江湖
  5. JS输入3个数,判断是否构成三角形,如构成,是直角还是锐角钝角三角形呢
  6. 2020.2.22GDUT寒假训练排位赛2-H
  7. Vue超详细(已完结)
  8. Android 导入v7包常见错误,以及项目引用v7包错误解决,
  9. 浙工大服务器实现优雅地上网
  10. 关键词采集网址软件【速度极快】