当前位置:首页 > 开发 > 编程语言 > Java > 正文

java 语法糖 分析(一,泛型与类型擦除)

发表于: 2014-09-18   作者:annan211   来源:转载   浏览次数:
摘要:   语法糖是一种计算机术语,是为了更加方便理解计算机语言或者说更便于编程而存在的,对编码的功能没有影响。    严格来说,几乎所有的人类编码,都算是语法糖的体现,只有计算机指令除外。    但是本文为了更好理解语法糖,站的角度略微不同。    在Java语言里,类型转换是无法预期的,有些时候 在编译期 编译器并不知道此
  语法糖是一种计算机术语,是为了更加方便理解计算机语言或者说更便于编程而存在的,对编码的功能没有影响。
   严格来说,几乎所有的人类编码,都算是语法糖的体现,只有计算机指令除外。
   但是本文为了更好理解语法糖,站的角度略微不同。

   在Java语言里,类型转换是无法预期的,有些时候 在编译期 编译器并不知道此类型转换能否成功,许多的转换异常 ClassCastException 就会被转嫁到运行期之中。
   Java中的泛型支持只存在源码之中,在编译器之后生成的字节码文件中就会被转换为原生类型,并且插入强制类型转换。对于运行期间的java代码来说 ,List<Integer> 和 List<String> 是一个类,他们都被转换成了List ,所以说 泛型是Java语言的一颗语法糖。java 语言中的泛型实现是基于类型擦除,基于类型擦除的泛型是伪泛型。
  
 
   public class GenericTest {

	public static void method(List<String> list){

	}

	public static void method(List<Integer> list){

	}

}
  


上面这段代码在编译期间就会报错
Method method(List<Integer>) has the same erasure method(List<E>) as another method in type GenericTest


有些筒子会认为这是Java的 方法重载,为什么会编译不通过。 按照上面的分析,编译器会忽略 泛型参数,两个方法都会被编译为

public static void method(List list){

	}


由于方法签名一模一样,编译器自然会不允许。

但是如果我们换一种方式

  class GenericTest2{
	public static int method(List<String> list){

		return 1;
	}

	public static void method(List<Integer> list){

	}
}


会发现 编译器会允许编译,执行也没有任何问题。

这又会挑战我们的另一个认知: Java方法的重载是不会考虑返回值的。

事实上 Java 的重载机制 确实是不会考虑方法的返回值的。
之所以 编译器允许通过 ,是因为 这两个方法 使用不同的返回值 使得他们可以共存于一个class文件里。 Java的 重载机制,只会涉及 方法名和参数列表,返回值是不参与重载选择的。
  Java 规范中 规定,只要描述不是完全一致的方法 ,是可以共存在一个class 文件里的。

以上解除异常的方案是毫无优雅可言的,我们可以得出,这里语法糖的所谓擦除,仅仅是对 code属性的字节码进行擦除,实际上元数据还是保留了泛型信息,我们可以通过反射抓取。

java 语法糖 分析(一,泛型与类型擦除)

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>
一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>
一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>
一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>
一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>
Java泛型-类型擦除 一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class,
Java泛型-类型擦除 一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class,
一、概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>
1 package com.xt.thinks15_7; 2 3 import java.util.Arrays; 4 5 class EraseObject1<A> { 6
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号