泛型

public interfaceFoo {}

public interfaceBar {}

public interfaceZar> {}

上面的代码有什么区别?

泛型初探

1、为何引入泛型?

Java 泛型也是一种语法糖,使用泛型可以在代码编译阶段完成类型的转换,避免代码在运行时强制转换而出现ClassCastException的异常。

网络搜索出来一大堆的名称解释,我们先看英文Generic type,从英文大概也能明白,Generic 这里可以理解为普通的,一般的,或者我们可以说通用的。

其实可以理解为Java中的一种类型,通用类型。

Java从1.5的版本就开始支持泛型,不过很多小伙伴对泛型还是模凌两可,今天大概讲讲泛型,基础好的小伙伴,就当复习复习。

在1.5版本以前

publicstaticvoidmain(String[] args){

List list = new ArrayList();

list.add("兔子托尼啊");

list.add(1234);

//正常运行

System.out.println((String)list.get(0));

//❌运行时报错

System.out.println((String)list.get(1));

}

从上面的代码可以看出了,第一句打印不报错,第二句打印会报错的。

List默认是Object的类型的,向List里面存数据都是没有问题的,但是取数据的时候,必须要要进行类型的转换。

List集合get数据的时候并不清楚里面存放的什么数据类型,默认取出来的都是Object的类型,如果取数据的时候转换的类型和原始存放存的类型不一样,会报ClassCastException的异常。

2、引入了泛型

看代码

List list = new ArrayList();

list.add("兔子托尼啊");

//❌编译时错误

list.add(1234);

//不需要再进行转换了

String str = list.get(0);

3、泛型带来好处

这在编码的时候就给我们解决了,类型转换的问题,可以放心写代码。

取数据的时候再也不要考虑我前面存的什么类型,我应该转换为什么类型,不怕类型转换报错。

类型擦除

上面讲了泛型,泛型虽然带来了好处,但是泛型也带了一个问题叫做类型擦除。

什么是类型擦除?

Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。

Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。

classGenericU{

publicvoidfoo(){

System.out.println("GenericU.foo()");

}

}

public classOperater {

private T obj;

publicOperater(T obj){

this.obj = obj;

}

publicvoiddoIt(){

//❌报错,提示找不到foo方法

obj.foo();

}

publicstaticvoidmain(String[] args){

GenericU genericU  = newGenericU();

Operater operater = newOperater<>(genericU);

operater.doIt();

}

}

上面的代码就是因为泛型擦除,带来编译就报错了,代码中的obj不知道是什么类型?

正确的代码应该是什么,只要指定T的类型就好

classOperater2 {

private T obj;

publicOperater2(T obj){

this.obj = obj;

}

publicvoiddoIt(){

//正确☑️

obj.foo();

}

}

区分在Operater2和Operater

必须指定泛型的类型。

上面的例子是运用在类上面的,方法中是什么效果呢?

classFoo{

//定义泛型方法..

public voidshow(T t){

System.out.println(t);

}

}

调用方法

publicstaticvoidmain(String[] args){

//创建Foo对象

Foo foo = newFoo();

//不同的类型参数

foo.show("兔子托尼啊");

foo.show(1234);

foo.show(12.34);

}

通配符与上下界

我们大家在java的源码中肯定看到这样的例子。一个下限,一个上限

? extends T VS ? super T

? extends T - 这里的?表示类型T的任意子类型,包含类型T本身。

? super T - 这里的?表示类型T的任意父类型,包含类型T本身。

上限通配符 可以代表未知的T类型,或者通过关键字 extends 所继承的T类的任何一个子类。

同样,下限通配符 可以代表未知的T类型,或者通过关键字super出来的的T类的任何一个父类。

通配符和泛型方法

//通配符

publicvoidfoo1(List> list){

}

//使用泛型方法

public voidfoo2(List t){

}

问: 上面两种代码都是可以的,但是什么场合用那种呢?

如果当参数之间有依赖关系,或者返回的参数有依赖关系则用泛型,反之则用通配符。

问:关于 ? extends T 和 ? super T 什么场景下用呢?

我从网上搜索了下

当你需要从一个数据结构中获取数据时(get),那么就使用 ? extends T;如果你需要存储数据(put)到一个数据结构时,那么就使用 ? super T; 如果你又想存储数据,又想获取数据,那么就不要使用通配符 ? ,即直接使用具体泛型T。

最后

泛型大概就讲了上面的内容,你看明白了吗?希望你又学到了,每天学一点,进步一点。升职加薪就是你了。

码字不易,关注后送福利,求关注。

java zar_唬人的Java泛型并不难相关推荐

  1. java 接口的泛型方法_Java泛型/泛型方法/通配符/泛型接口/泛型泛型擦出

    从JDK1.5以后引入了三大常用新特性:泛型.枚举(enum).注解(Annotation).其中JDK1.5中泛型是一件非常重要的实现技术,它可以帮助我们解决程序的参数转换问题.本文为大家详细介绍一 ...

  2. Java基础语法十二 泛型程序设计

    1 意义 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 常见应用 : ArrayList 2 K T V E ? object等的含义 类型变量使用大写形式 E – Element ( ...

  3. 泛型java实例_【Java学习笔记】Java6泛型实例

    你若是不使用泛型,则会这样处理数据类型不确定的问题: class Stash { private Object x; void set(Object x) { this.x = x; } Object ...

  4. java泛型类指定多个泛型_Java泛型中的多态

    java泛型类指定多个泛型 从作为Java程序员的早期开始,我们都知道如何实例化和使用Collection对象. 实例化为具体类的List接口将如下所示. List myArrayList = new ...

  5. 二、Java 面向对象高级——Collection、泛型

    day02[Collection.泛型] 主要内容 Collection集合 迭代器 增强for 泛型 教学目标 能够说出集合与数组的区别 说出Collection集合的常用功能 能够使用迭代器对集合 ...

  6. 【Java】Collection集合和泛型

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

  7. JAVA进阶教学之(泛型)

    泛型 引言: 泛型:泛型允许程序员在编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型 人话:泛型对规定范围产生约束,约束后只能存储泛型指定的类型 诞生:JDK5.0以后 作用:泛型旨 ...

  8. android 生成泛型对象,java android解析多层含有泛型对象的json数据获取不到泛型类型解析失败解决办法...

    ####问题描述 * java 解析多层含有泛型对象的json数据获取不到泛型类型 * 如果将泛型改成实际的类型就能正常解析 * 如果不改成实际的类型泛型数据被解析成com.google.gson.i ...

  9. Java通过反射了解集合泛型的本质(Class反射都是在运行时执行的)

    目录 理论 实例 理论 Class的反射都是运行时候来执行的,Java中集合的泛型是为了防止错误的输入,只在编译阶段有效,绕过编译就无效了. 下面演示用反射绕过编译器, 实例 程序结构: 运行截图如下 ...

最新文章

  1. CSDN博客获取积分规则!不是下载积分!如何快速增长积分!
  2. FusionCharts下载地址汇总及更新介绍
  3. 奇妙的棋盘(建图+搜索)
  4. c语言数组数据用指针查找,c语言数组与指针_指针篇_2011.ppt
  5. wxWidgets:wxAuiNotebook类用法
  6. c语言里字符串和字符串字面量,string literals(字符串字面量)
  7. Python rabbitmq的使用(五)
  8. 阿里云物联网平台体验(树莓派+Python篇)
  9. C# ASP.NET MVC 之 SignalR 学习 实时数据推送显示 配合 Echarts 推送实时图表
  10. Mariadb 安装 启动 及错误 1067 问题解决
  11. 医院预约挂号系统 ssm
  12. python快速接手别人的代码_Python 爬虫代码,网上找的别人的,但是报错,求高手指点...
  13. OpenCv算法的基本介绍与应用
  14. 用 Python selenium爬取股票新闻并存入mysql数据库中带翻页功能demo可下载
  15. OLED、QLED、miniled、microled的区别与优劣势是什么?(非商业转载)
  16. 学习opencv:PS滤镜—曝光过度
  17. 看图学习VMWare以及常见问题答疑(转)
  18. 各品牌主板设置U盘启动方法以及菜单快捷键
  19. 【转载】Oracle字符集子集与超级的对应关系
  20. HTML 基础 结构

热门文章

  1. 线程等待通知 linux,Java 线程协作 wait(等待)与 notiy(通知)
  2. matlab melbankm,Matlab v_melbankm函数参数详解(英文附例)
  3. linux c 封装redis,封装hiredis——C++与redis对接(一)(string的SET与GET操作)
  4. python数据集的预处理_关于Pytorch的MNIST数据集的预处理详解
  5. 手把手教你爬虫requests实战演练——python篇
  6. inuri .php id=,php常用函数(遇见就补充)
  7. C++运算符重载函数作为类成员函数和友元函数
  8. python crm_Python CRM项目一
  9. python 数据库查询返回list或tuple
  10. echarts.js:1136 Uncaught Error: Initialize failed: invalid dom.