项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步

1.为什么需要泛型

我们知道java是属于强类型编程语言。变量在使用之前,需要先进行定义,而定义个变量时必须要指定其数据类型,这样编译器在编译阶段就能将很多类型错误消灭在萌芽状态。

如果我们有这样一个需求:定义一个坐标类。但是该坐标类的数据类型可能是整数,也可以能是小数,还有可能是字符串。举个例子

x=10; y=15;
x="东经116",y="北纬39"
x=10.01; y=15

坐标有可能是整型,也有可能是字符串类型,还有可能是double类型。如果没有泛型,我们可能会这么做

package edu.bit.test;public class ObjectType {public static void main(String[] args) {Point p = new Point();p.setX(10);p.setY(15);//向下转型,此时没有问题,代码能正常运行int x = (Integer)p.getX();int y = (Integer)p.getY();System.out.println(p);p.setX("东经116");p.setY("北纬39");//此时向下转型会有问题double x1 = (Double)p.getX();double y1 = (Double)p.getY();System.out.println(p);}
}class Point {Object x = 0;Object y = 0;public Object getX() {return x;}public void setX(Object x) {this.x = x;}public Object getY() {return y;}public void setY(Object y) {this.y = y;}@Overridepublic String toString() {return "Point{" +"x=" + x +", y=" + y +'}';}
}

将代码run起来

Point{x=10, y=15}
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Doubleat edu.bit.test.ObjectType.main(ObjectType.java:22)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:497)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)Process finished with exit code 1

在上面的示例代码中,用的是Object类型。这样,在调用set方法的时候是没有问题的。但是在使用get方法时,因为需要将Object类向下转型成其他类,这样容易带来问题。并且,这种问题在jdk编译阶段还不容易被发现,往往只有在运行的时候才会抛出异常!像我们上面的代码,在IDE中是不会报错的,但是代码run起来以后,会抛出一个ClassCastException的异常!

2.泛型的使用方式

将上面的代码改用泛型的方式实现

package edu.bit.test;public class GenericType {public static void main(String[] args) {Point1<Integer,Integer> p1 = new Point1<Integer, Integer>();p1.setX(10);p1.setY(15);System.out.println(p1);Point1<String,String> p2 = new Point1<String,String>();p2.setX("东经116");p2.setY("北纬39");System.out.println(p2);}}class Point1<T1,T2> {T1 x;T2 y;public T1 getX() {return x;}public void setX(T1 x) {this.x = x;}public T2 getY() {return y;}public void setY(T2 y) {this.y = y;}@Overridepublic String toString() {return "Point1{" +"x=" + x +", y=" + y +'}';}
}

将代码run起来

Point1{x=10, y=15}
Point1{x=东经116, y=北纬39}

在上面的例子里,直接将Point1类定义为泛型类。泛型类的定义方法为类名后面用尖括号将<T1,T2>包起来,其中的T1,T2是我们自己定义的类标志符,用来表示数据的类型。并且注意的是,T1,T2只是类型标识的占位符,编译阶段并不会真正确定类型,只有在运行阶段才会替换为真正的数据类型。

使用泛型的好处是:当我们在是使用泛型的时候,即指定了数据类型,又可以根据需要灵活使用不同数据类型,在使用严谨性与灵活性之间做了一个很好的兼顾。尤其是在各种框架中,泛型的使用非常广泛。

3.限制泛型的使用类型

在我们上面的代码中,没有对参数类型做任何限制,可以使用任何类型的参数。然后在很多实际场景中,还是需要对参数类型做一定限制的,只能传递部分参数类型,传递其他类型则会引发错误。例如在前面的Point类中,我们希望用户只能传递数字类型,而不能传递字符串等其他类型:

package edu.bit.test;public class GenericSmallType {public static void main(String[] args) {Point2<Integer,Integer> p1 = new Point2<Integer,Integer>();p1.setX(10);p1.setY(15);System.out.println(p1);Point2<Double,Double> p2 = new Point2<Double,Double>();p2.setX(10.0);p2.setY(15.01);System.out.println(p2);}
}class Point2<T1 extends Number,T2 extends Number> {public T1 x;public T2 y;public T1 getX() {return x;}public void setX(T1 x) {this.x = x;}public T2 getY() {return y;}public void setY(T2 y) {this.y = y;}@Overridepublic String toString() {return "Point2{" +"x=" + x +", y=" + y +'}';}
}

将代码run起来:

Point2{x=10, y=15}
Point2{x=10.0, y=15.01}

4.类型擦除(type erasure)

java字节码中不包含有泛型的类型信息。编译器在编译阶段去掉泛型信息,在运行的时候加上类型信息,这个过程被称为类型擦除。
我们在使用泛型的过程中,如果没有指定数据类型,那么将会擦除泛型类型。

package edu.bit.test;public class TypeErasure {public static void main(String[] args) {Point3 p1 = new Point3();p1.setX("东经116");p1.setY("北纬39");//向下转型String longitude = (String)p1.getX();String latitude = (String)p1.getY();System.out.println(p1);}
}class Point3<T1,T2> {public T1 x;public T2 y;public T1 getX() {return x;}public void setX(T1 x) {this.x = x;}public T2 getY() {return y;}public void setY(T2 y) {this.y = y;}@Overridepublic String toString() {return "Point3{" +"x=" + x +", y=" + y +'}';}
}

本例中,创建Point3对象的时候没有指定数据类型。编译器在处理的时候,会将所有数据向上变为Object类型。然而这样处理完以后,使用get方法的时候,又需要向下转型。这样的话,跟第一部分没有使用泛型就一样了!

java泛型通俗讲解相关推荐

  1. Java线程通俗讲解

    Java线程介绍 通常情况下,在一个服务器上面运行的程序是很多的,可能同一时间会有多个客户 端的程序访问服务器,服务器都要对这些客户端做出响应.如果我们处理器有限, 只有一个处理器的时候,如何能够让这 ...

  2. Java泛型详解-史上讲解最详细的,没有之一

    目录 1. 概述 2. 一个栗子 3. 特性 4. 泛型的使用 4.1 泛型类 4.2 泛型接口 4.3 泛型通配符 4.4 泛型方法 4.4.1 泛型方法的基本用法 4.4.2 类中的泛型方法 4. ...

  3. Java基础之泛型简单讲解(通俗易懂)

    Java基础之泛型简单讲解(通俗易懂) 1. 前言 2. 简单例子对比理解 2.1 未使用泛型例子--ArrayList 2.2 使用泛型的例子 2.2.1 ArrayList 举例 2.2.2 Ha ...

  4. Java多数据源最通俗讲解

    Java多数据源最通俗讲解 before after 理论 实操 编码 小总结 before 项目中可能会用到很多的数据源,例如目前这个项目中用到了五个数据源,那么数据源的 配置和数据源的切换就成为了 ...

  5. java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一,大厂 HR 如何面试

    写在最前面,我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家.扫码加微信好友进[程序员面试学习交流群],免费领取.也欢迎各位一起在群里探讨技术. 对j ...

  6. java泛型(360°无死角讲解)

    什么是泛型 Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构.泛型的本质就是参数化类型,也就是所操作的数据 ...

  7. java泛型特点_java泛型简单总结

    Java泛型简单总结 1)基本概念: 泛型(Generic Type或Generics)是 对Java语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看做是使用参数化类型时 ...

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

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

  9. 一文搞懂 Java 泛型,非常详细!

    作者: ZiWenXie http://www.ziwenxie.site/2017/03/01/java-generic/ 引言 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广 ...

  10. java泛型的作用和实现原理_java泛型的作用及实现原理

    一.泛型的介绍 泛型是Java 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Ja ...

最新文章

  1. Android studio 编译器导入一个背景图片
  2. 东莞厚街工业机器人展会_工业机器人四大家族齐聚!东莞将在12月举办智博会...
  3. 【转】BT5汉化步骤
  4. springmvc二十七:springmvc-ResponseBody与ResponseEntity
  5. 我们编写的C代码是怎样跑起来的?
  6. Flex开发中遇到未整理资源
  7. RS-232 vs. TTL Serial Communication(转载)
  8. 解决文件上传_使用FastDfs上传头像上传不成功的问题---SpringCloud Alibaba_若依微服务框架改造---工作笔记002
  9. 企业数据安全防护不可忽视,数据丢失/损坏如何处理?
  10. java模式:深入单例模式
  11. 京瓷1020手动双面打印提示_自动双面打印时纸张是如何被翻转的?
  12. 阿里云服务器搭建私人云盘
  13. 飞秒激光制备量子计算机,制备出世界最大规模光量子计算芯片
  14. 自动驾驶常用传感器介绍
  15. Compose 这次要送 Pixel 5 了!
  16. (三)Latex的字体字号设置
  17. ECMAScript 6 简明教程(一文搞懂ES6)
  18. FCoin币改试验区(主版C)筹备公告(5号)
  19. CSS 关键字 initial、inherit 和 unset
  20. Ubuntu22.04 美化

热门文章

  1. 使用宝塔控制面板建站时出现网页出现404错误怎么办?
  2. 基础 网络架构 网络硬件名词 网络通信协议
  3. Windows下QQ聊天记录中图片的默认存放位置
  4. 编写可靠shell脚本的8个建议
  5. 文件比较 增量 更新 系统发布 增量更新
  6. android中页面跳转以及数据在Activity之间的传递
  7. Python命令行参数选择
  8. 在vs中用正则表达式查找字符并替换
  9. 记我朋友的一次前端面试
  10. Spanning Tree Protocol (STP) in NetScaler Appliance