泛型的定义:

在定义类的时候并不会设置类的属性和方法的参数的具体类型,而是在类实际用的时候再定义。它存在的意义是帮我们在编译期间检查我们的类型是否正确。

//定义一个Point类
class Point{private Object x;private Object y;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;}
}public class Generic {public static void main(String[] args) {//创建Point类对象Point point = new Point();//定义X和Ypoint.setX("东经80度");point.setY("北纬20度");//转成字符串类型String x = (String) point.getX();String y = (String) point.getY();//打印System.out.println("x = "+x);System.out.println("y = "+y);}
}

我们先定义一个Point类,其中的X和Y属性我们都用定义为Object类,在使用的时候转成字符串,再进行打印。

但是当我们setY的时候给了它一个整数,但是后面转换成字符串的时候,编译器并没有个我们提示类型错误,只有到运行的时候在产生报错。

告诉我们34行产生类型转化错误,所以就产生类泛型,目的是可以帮助我们在编译器期间就可以告诉我们类型错误,及时修改!

泛型类:

基本语法:

class exampleClass<T>{
}

这里的尖括号中的T表示类型参数,可以指代任何类型。
这里的T可以用任意符号代替,但是java中会给出了一些标准。

T:代表一般的类
E:代表Element元素和Exception异常
K:代表key
V:代表Value,通常会配合K一起使用(只能出现一个K,K有它对应的Value,键值对)
S:代表Subtype子类型

我们利用泛型类将上面的代码再写一遍

//定义一个泛型Point类
class Point<T>{private T x;private T y;public T getX() {return x;}public void setX(T x) {this.x = x;}public T getY() {return y;}public void setY(T y) {this.y = y;}
}public class Generic {public static void main(String[] args) {//创建Point类对象Point<String> point = new Point<String>();//定义X和Ypoint.setX("东经80度");point.setY("北纬30度");//转成字符串类型String x = (String) point.getX();String y = (String) point.getY();//打印System.out.println("x = "+x);System.out.println("y = "+y);}
}

和之前的代码没有太多的差距,但是我们再将Y定义成一个int类型的数据看一下效果。

编译器提醒我们在32行出现了错误需要我们进行修改!这就是泛型存在的意义。

泛型方法:

基本语句:

class exampleClass<T>{
      public <E> E exampleMethod(E e){
         System.out.println(e);
         return e;
      }
}

第一个<E>表示这个方法是一个泛型方法;
第二个E表示方法的返回值类型是E;
括号中的E表示传入的参数的类型是E,这个E被称为是参数化类型。
泛型类和泛型方法是可以共存的,在泛型类中有泛型方法,他们俩尖括号中的内容不是一定要相同的,泛型方法的参数类型是单独的 ,与泛型类无关!

泛型接口:

基本语法:

interface IMessage<T>{
public void print(T t);
}

子类实现这个接口:
(1)子类仍然是泛型类:

//定义一个泛型接口
interface IMessage<T>{//抽象方法public void print(T t);
}
//定义一个类实现泛型接口
class MessageImpl1<T> implements IMessage<T>{//覆写泛型接口的方法@Overridepublic void print(T t) {System.out.println(t);}
}

(2)子类给出具体类型(子类就不是泛型类了):

//给出具体类型的类就不是泛型类了
class MessageImpl2 implements IMessage<Integer>{//覆写接口方法@Overridepublic void print(Integer integer) {}
}

通配符:

问号通配符:<?>
当我们定义了一个泛型类,在写一个方法的时候,要将这个泛型类当做参数传入,但是我们这是不能确定这个泛型类的具体类型,所以就有了问号通配符,帮我们接受这个泛型类包含的所有数据类型。

//泛型类
class exampleClass2<T>{T t;//定义fun方法//利用问号通配符,接收泛型类所包含的所有数据类型public static void fun(exampleClass2<?> exampleClass){System.out.println(exampleClass);}
}

但是用问号通配符的方法不可以修改泛型类对象的值,因为我们在这是不知道该属性的类型,所有不能进行修改。我们只能获取它的值,不能修改

这里77行我们试图修改,编译器就会提醒有错误。

上限通配符:<? extends A>

//泛型类
class exampleClass3<T>{T t;//上限通配符public static void fun(exampleClass3<? extends Number> exampleClass3){System.out.println(exampleClass3);}
}

上限通配符与问号通配符的不同就是让问号继承了一个父类,这个这个方法只会接受这个父类及其子类的类型。
这里也是不清楚该方法具体传入的参数的类型,所以也是只能获取不能修改

95行修改时报错。
下限通配符:<? super B>

//泛型类
class exampleClass4<T>{T t;//下限通配符public static void fun(exampleClass4<? super Number> exampleClass4){System.out.println(exampleClass4);}
}

下限通配符表示方法只能接收该类及其所有的父类的类型。
这里我们清楚所有的传入数据不是当下这个就是它的父类,所以可以通过向上转型进行修改,这里是一个天然的向上转型。

这里我们在修改的时候就不会报错。

三种通配符的使用特点:
1、三种通配符都可以用在方法上
2、只有上限通配符还可以用在泛型类和泛型接口的声明上
3、问号通配符和上限通配符只能获取数据不能修改
4、只有下限通配符可以对元素进行修改

类型擦除:

泛型只存在于编译阶段,当进入JVM中所有的泛型内容都会被擦除。普通泛型擦除为Object;有泛型上限的擦除为相应的泛型上限;有泛型下限的,擦除为相应的反省下限。反省的存在就只是为了在编译阶段帮助程序员检查类型错误的,所以在运行是它的意义就失去了。

泛型(泛型类、泛型方法、泛型接口、通配符)详解相关推荐

  1. 鸟欲高飞先振翅,人求上进先读书 [泛型 泛型类 泛型方法 泛型接口 泛型通配符详解]

    文章目录 5. 泛型 5.1 泛型概述[理解] 5.2 为什么会引入泛型? 5.3 泛型的好处 5.4 泛型的定义格式 5.5 泛型类[应用] 5.6 泛型方法 5.7 泛型接口[应用] 5.8类型通 ...

  2. Java 泛型(generics)详解及代码示例、Java 类型通配符详解及代码示例

    Java 泛型(generics)详解及代码示例.Java 类型通配符详解及代码示例 - 概念 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制 ...

  3. Java泛型的定义和使用详解

    目录 一,为什么我们需要泛型 二,什么是泛型,泛型的定义 三,如何定义和使用泛型 四.限定类型变量 五.泛型中的约束和局限性 六.泛型类型的继承规则 七.通配符类型 八.虚拟机是如何实现泛型的? 一, ...

  4. c# combobox集合数据不显示_C#实战036:各种泛型的定义和使用详解

    什么是泛型(Generic) 顾名思义,就是明确定义类型,只有在使用的时候蔡需要指定类型,这时泛型中的参数会被相应的值类型替换.当我们有多个方法相同只是类型不同时我们就可以定义一个泛型方法,除了方法泛 ...

  5. 【Flutter】Dart 泛型 ( 泛型类 | 泛型方法 | 特定类型约束的泛型 )

    文章目录 一.Dart 泛型类与泛型方法 二.Dart 泛型中的特定类型约束 三.Dart 自带泛型 四.完整代码示例 五. 相关资源 一.Dart 泛型类与泛型方法 泛型作用 : 为 类 , 接口 ...

  6. linux通配符详解

    linux中常用的通配符: 通配符 作用 * 匹配0个或多个任意字符 ? 匹配任意单个字符 [abc] 匹配abc中的任意单个字符 [!abc] 匹配除abc中的任意单个字符 [a-z] 匹配a-z中 ...

  7. Java 泛型中的通配符详解

    目录 1.如何定义和使用上界通配符? 2.如何定义和使用无界通配符? 3.如何定义和使用下界通配符? 4.如何使用通配符定义泛型类或接口之间的子类型关系? 5.通配符的捕获和辅助方法 6.通配符使用指 ...

  8. Java泛型三:通配符详解extends super

    在java泛型中,? 表示通配符,代表未知类型,< ? extends Object>表示上边界限定通配符,< ? super Object>表示下边界限定通配符. 通配符 与 ...

  9. 反掩码/掩码/通配符详解

    目录 一.反掩码 二.掩码 三.通配符 四.选择题 五.总结 一.反掩码 在反掩码中,1表示随机,0表示精确匹配: 0和1,永远不交叉: 0永远在左边,1永远在右边: 在路由协议的配置中,通过netw ...

  10. java模型给泛型_java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

    对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应 ...

最新文章

  1. MIT重磅报告:一文看清AI商业化现状与未来
  2. C#筛法求出范围内的所有质数
  3. FPGA的设计艺术(2)FPGA开发流程
  4. html 失效,如何让css失效?
  5. Android中ContentProvider组件数据共享
  6. 为什么世界上没有安全的工作
  7. 使用go语言开发一个后端gin框架的web项目
  8. Linux sz rz
  9. 路由器的软件测试,路由器测试方法 - 软件测试网 _领测软件测试网站-中国软件测试技术第一门户...
  10. 屏幕录像专家v2016破解版
  11. 计算机截图工具无法运行,win7系统打开截图工具提示“截图工具当前未在计算机上运行”的解决方法...
  12. 深入了解gorm Scan的使用
  13. 【等保测评】等保测评师怎么考,前景怎么样?
  14. 解决创建MAVEN工程速度慢的问题
  15. Python 通过 Tushare Pro 获取财经数据接口
  16. 【excel】SUMIF合并单元格
  17. fedora34 不显示桌面图标
  18. Nmap命令详解(全)
  19. 友元(友元函数、友元类、类成员函数的友元)
  20. firefox 绿色护眼

热门文章

  1. 非常量引用的初始值必须是左值的处理方法
  2. 小程序input绑定输入保存数据
  3. 响应式网站建设的优缺点
  4. Verilog实现千兆以太网传输
  5. android 墓碑日志,关于清明节扫墓的日记
  6. cadence allegro番外:制作flash焊盘
  7. 2016年第七届java A组蓝桥杯省赛真题
  8. Intellij IDEA如何恢复删除的文件或文件夹
  9. java 多次正则匹配_Java正则多次匹配和多次组匹配
  10. 曲线曲面基本理论(二)