`
annan211
  • 浏览: 463112 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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

    博客分类:
  • jvm
 
阅读更多
  语法糖是一种计算机术语,是为了更加方便理解计算机语言或者说更便于编程而存在的,对编码的功能没有影响。
   严格来说,几乎所有的人类编码,都算是语法糖的体现,只有计算机指令除外。
   但是本文为了更好理解语法糖,站的角度略微不同。

   在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-Edge#Java-Interview-Tutorial#Java语法糖之泛型与类型擦除1

    - 泛型擦除前的例子把这段Java代码编译成Class文件,然后再用字节码反编译后,將会发现泛型都不见了,又变回了Java泛型出现之前的写法,泛型类型都变回了原

    解析Java泛型的类型擦除.pdf

    在 Java 语言中,泛型类型擦除的机制使得开发者难以理解和使用泛型,例如,在 Java 中,我们可以定义一个泛型类 `ArrayList&lt;T&gt;`,其中 `T` 是类型参数,但是,在编译后的字节码文件中,泛型类型信息已经被擦除,所有...

    Java集合框架及泛型

    1. **类型擦除**: Java泛型在编译后会进行类型擦除,也就是说,所有的泛型类在运行时都会退化为未使用泛型的原始形式。这意味着在运行时无法检查泛型类型,但编译时的类型检查可以避免很多错误。 2. **边界通配符**...

    Java泛型_Java中的泛型结构_

    - 类型擦除:Java编译器会进行类型擦除,将泛型类的实例转换为无参数类型,但会在编译时进行类型检查。 3. 泛型接口: - 定义与实例化与泛型类类似,例如 `interface MyInterface&lt;T&gt; { ... }`,然后 `MyInterface...

    java 泛型方法使用示例

    需要注意的是,Java的泛型是通过类型擦除来实现的。这意味着在运行时,所有关于泛型的信息都会被删除,因此泛型只在编译时起作用。这也就意味着你不能在运行时通过反射获取到泛型的具体类型信息。 **七、总结** ...

    java 多态的泛型实现

    此外,泛型还提供了类型擦除的机制。由于Java是静态类型的语言,无法在运行时直接使用类型参数,因此编译器会在生成字节码时将所有类型参数替换为它们的实际类型或者Object。这种机制确保了泛型与Java的现有类型系统...

    博客《夯实JAVA基本之一——泛型详解(2)》对应源码

    博客可能还讨论了类型擦除,这是Java泛型的一个关键特征。由于Java的泛型是编译时检查的,因此在运行时,所有的泛型信息都会被“擦除”,转化为原始类型。这意味着泛型不提供运行时类型检查,但它们增强了静态类型...

    Java语言 泛型讲解案例代码 (泛型类、泛型接口、泛型方法、无界及上下限通配符、泛型对协变和逆变的支持、类型擦除 ...)

    本代码资源是一个关于Java语言中泛型的讲解案例代码。通过使用实际的示例代码,详细讲解了泛型的定义、用法和优势。 适用人群: 有一定Java编程基础的开发者;对泛型概念感兴趣或希望加深理解的学习者。 使用场景...

    Java-泛型.ppt

    Java泛型的一个重要特点是**类型擦除**。这意味着在编译之后,所有的泛型信息都会被擦除,仅保留原始类型。这意味着泛型实际上只是一个编译时的检查机制,运行时不会保留泛型信息。例如,`List&lt;Integer&gt;`和`List...

    java泛型初探

    **类型擦除**:Java泛型在编译后会进行类型擦除,这意味着运行时不会保留任何关于类型的元数据。因此,泛型的主要作用在于编译期,用于检查类型安全。 **通配符**:在某些情况下,我们可能需要处理多种类型但又不...

    [Java泛型和集合].(Java.Generics.and.Collections).文字版

    - **类型擦除**:Java泛型在编译后会被擦除,但在编译时提供了类型检查。 Maurice Naftalin和Philip Wadler的书籍会详细探讨这些概念,并通过实例解释如何在实际项目中应用泛型和集合。书中的文字版内容可能涵盖: ...

    《剑指offer》Java中的语法糖

    泛型是一种语法糖,在 JDK1.5 中引入了泛型机制,但是泛型机制的本身是通过类型擦除来实现的。在 JVM 中没有泛型,只有普通类型和普通方法,泛型类的类型参数,在编译时都会被擦除。例如: ```java List&lt;Integer&gt; a...

    Java泛型使用详细分析.docx

    需要注意的是,Java的泛型是类型擦除的,这意味着在运行时,所有的泛型信息都会被擦除,实际的类型检查都在编译期间完成。因此,泛型不会影响程序的运行时性能。 总的来说,Java泛型增强了代码的类型安全性,提高...

    java 泛型的使用 详细讲解

    这意味着所有的泛型类型都会转化为它们的基类型,如`List&lt;T&gt;`变为`List`。 示例: ```java List&lt;String&gt; stringList = new ArrayList(); List&lt;Integer&gt; intList = new ArrayList(); System.out.println(stringList...

    Java核心知识1:泛型机制详解.pdf

    为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的...

    Java泛型研究.pdf

    Java泛型是Java语言中的一种重要机制,自从Java 1.5版本引入泛型以来,Java开发者可以更方便地编写类型安全的代码。泛型的引入解决了Java早期版本中类型不安全的问题,提高了Java语言的开发效率和安全性。 泛型的...

    学习泛型语法3

    4. **类型擦除**:Java中的泛型在编译后会进行类型擦除,因此在运行时无法直接获取类型参数的信息。但是,编译器会在编译时进行类型检查,防止错误的类型操作。 5. **边界约束**:使用`&lt;T extends SomeClass&gt;`限制...

    Java1.5泛型指南

    #### 一、引言:Java 1.5 泛型的重要性与背景 在Java 1.5版本中,引入了泛型(Generics)这一重要的特性,为类型安全性和代码重用性带来了革命性的改变。在此之前,开发人员在处理集合类时,如`List`或`Set`,往往...

Global site tag (gtag.js) - Google Analytics