详解java 中泛型中的类型擦除和桥方法

 更新时间:2017年06月22日 11:10:18   投稿:lqh  
这篇文章主要介绍了详解java 中泛型中的类型擦除和桥方法的相关资料,需要的朋友可以参考下

在Java中,泛型的引入是为了在编译时提供强类型检查和支持泛型编程。为了实现泛型,Java编译器应用类型擦除实现:

       1、  用类型参数(type parameters)的限定(如果没有就用Object)替换泛型类型中的所有类型参数。

       2、  需要保持类型安全的时候加入类型转换

       3、  在extened 泛型类型中生成桥方法来保证多态性

   类型擦除确保不会为已参数化了的类型(paramterized types)产生新类,这样泛型能保证没有运行时的负载。

泛型类型擦除

      在类型擦除过程中,java编译器擦除所有类型参数,用它的限定或者Object(没限定时)替换。

     考虑下面的泛型类:

public class Node<T> { 
 
 private T data; 
 private Node<T> next; 
 
 public Node(T data, Node<T> next) } 
  this.data = data; 
  this.next = next; 
 } 
 
 public T getData() { return data; } 
 // ... 
} 

因为类型参数T是非限定的,Java编译器使用Object替换它:

public class Node { 
 
 private Object data; 
 private Node next; 
 
 public Node(Object data, Node next) { 
  this.data = data; 
  this.next = next; 
 } 
 
 public Object getData() { return data; } 
 // ... 
} 

下面的例子,泛型Node类使用了限定类型参数:

public class Node<T extends Comparable<T>> { 
 
 private T data; 
 private Node<T> next; 
 
 public Node(T data, Node<T> next) { 
  this.data = data; 
  this.next = next; 
 } 
 
 public T getData() { return data; } 
 // ... 

编译器会使用第一个限定类,Comparable替换限定参数类型T:

public class Node { 
 
 private Comparable data; 
 private Node next; 
 
 public Node(Comparable data, Node next) { 
  this.data = data; 
  this.next = next; 
 } 
 
 public Comparable getData() { return data; } 
 // ... 
} 

同样,泛型方法也可以擦除。规则类似,不细说。

类型擦除的影响和桥方法

有时候类型擦除会引起无法预知的情况。比如:

给定以下两个类:

public class Node<T> { 
 
 public T data; 
 
 public Node(T data) { this.data = data; } 
 
 public void setData(T data) { 
  System.out.println("Node.setData"); 
  this.data = data; 
 } 
} 
 
public class MyNode extends Node<Integer> { 
 public MyNode(Integer data) { super(data); } 
 
 public void setData(Integer data) { 
  System.out.println("MyNode.setData"); 
  super.setData(data); 
 } 
} 

考虑以下代码:

MyNode mn = new MyNode(5); 
Node n = mn;   // 原生类型 – 编译器会给出未检查警告 
n.setData("Hello");  
Integer x = mn.data; // 会引发抛出ClassCastException 

 类型擦除后,代码变成:

MyNode mn = new MyNode(5); 
Node n = (MyNode)mn;   //原生类型 – 编译器会给出未检查警告 
n.setData("Hello"); 
Integer x = (String)mn.data; //会引发抛出ClassCastException 
public class Node { 
 
 public Object data; 
 
 public Node(Object data) { this.data = data; } 
 
 public void setData(Object data) { 
  System.out.println("Node.setData"); 
  this.data = data; 
 } 
} 
 
public class MyNode extends Node { 
 
 public MyNode(Integer data) { super(data); } 
 
 public void setData(Integer data) { 
  System.out.println("MyNode.setData"); 
  super.setData(data); 
 } 
} 

类型擦除后,方法的签名已经不匹配。Node 方法变成setData(Object),MyNode方法变成setData(Integer)。MyNode setData方法已经不是覆盖Node setData方法。

为了解决这个问题,维持泛型类型的多态性,java编译器会生成一个桥方法:

class MyNode extends Node { 
 
 // 编译器生成的桥方法 
 // 
 public void setData(Object data) { 
  setData((Integer) data); 
 } 
 
 public void setData(Integer data) { 
  System.out.println("MyNode.setData"); 
  super.setData(data); 
 } 
 
 // ... 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • MyBatis中如何获取Oracle序列

    MyBatis中如何获取Oracle序列

    文章介绍了在使用MyBatis时,如何通过获取序列的下一个值来完成某些功能操作,并在之后进行数据的添加操作,文中特别强调了在获取序列值后不能单独执行插入操作,否则会报错
    2024-12-12
  • 一行命令同时修改maven项目中多个module的版本号的方法

    一行命令同时修改maven项目中多个module的版本号的方法

    这篇文章主要介绍了一行命令同时修改maven项目中多个module的版本号的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-06-06
  • Java中实现简单的Excel导出

    Java中实现简单的Excel导出

    今天小编就为大家分享一篇关于Java中实现简单的Excel导出,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Java中的Vector和Stack底层源码分析

    Java中的Vector和Stack底层源码分析

    这篇文章主要介绍了Java中的Vector和Stack底层源码分析,Stack继承了Vector,Vector底层还是一个List,也就是基于数组来实现的,所以ArrayList有的优点,比如获取元素的速度快,随机读,它都有,需要的朋友可以参考下
    2023-12-12
  • Java加权负载均衡策略实现过程解析

    Java加权负载均衡策略实现过程解析

    这篇文章主要介绍了Java加权负载均衡策略实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • 详解java中spring里的三大拦截器

    详解java中spring里的三大拦截器

    在本篇文章里我们给大家详细讲述了java中spring里的三大拦截器相关知识点以及用法代码,需要的朋友们学习下。
    2018-10-10
  • Java实现读取及生成Excel文件的方法

    Java实现读取及生成Excel文件的方法

    这篇文章主要介绍了Java实现读取及生成Excel文件的方法,结合实例形式分析了java通过引入第三方jar包poi-3.0.1-FINAL-20070705.jar实现针对Excel文件的读取及生成功能,需要的朋友可以参考下
    2017-12-12
  • SpringMVC 中配置 Swagger 插件的教程(分享)

    SpringMVC 中配置 Swagger 插件的教程(分享)

    下面小编就为大家分享一篇SpringMVC 中配置 Swagger 插件的教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • java使用java.util.Date获取指定日期的年、月、日、时、分、秒

    java使用java.util.Date获取指定日期的年、月、日、时、分、秒

    在Java中获取当前时间和日期是很常见的操作,也是很重要的操作,下面这篇文章主要给大家介绍了关于java使用java.util.Date获取指定日期的年、月、日、时、分、秒的相关资料,需要的朋友可以参考下
    2024-01-01
  • Java中的随机数详解

    Java中的随机数详解

    这篇文章主要介绍了Java中的随机数,需要的朋友可以参考下
    2014-02-02

最新评论