语法糖是一种计算机术语,是为了更加方便理解计算机语言或者说更便于编程而存在的,对编码的功能没有影响。
严格来说,几乎所有的人类编码,都算是语法糖的体现,只有计算机指令除外。
但是本文为了更好理解语法糖,站的角度略微不同。
在Java语言里,类型转换是无法预期的,有些时候 在编译期 编译器并不知道此类型转换能否成功,许多的转换异常 ClassCastException 就会被转嫁到运行期之中。
Java中的泛型支持只存在源码之中,在编译器之后生成的字节码文件中就会被转换为原生类型,并且插入强制类型转换。对于运行期间的java代码来说 ,List<Integer> 和 List<String> 是一个类,他们都被转换成了List ,所以说 泛型是Java语言的一颗语法糖。java 语言中的泛型实现是基于类型擦除,基于类型擦除的泛型是伪泛型。
上面这段代码在编译期间就会报错
有些筒子会认为这是Java的 方法重载,为什么会编译不通过。 按照上面的分析,编译器会忽略 泛型参数,两个方法都会被编译为
由于方法签名一模一样,编译器自然会不允许。
但是如果我们换一种方式
会发现 编译器会允许编译,执行也没有任何问题。
这又会挑战我们的另一个认知: Java方法的重载是不会考虑返回值的。
事实上 Java 的重载机制 确实是不会考虑方法的返回值的。
之所以 编译器允许通过 ,是因为 这两个方法 使用不同的返回值 使得他们可以共存于一个class文件里。 Java的 重载机制,只会涉及 方法名和参数列表,返回值是不参与重载选择的。
Java 规范中 规定,只要描述不是完全一致的方法 ,是可以共存在一个class 文件里的。
以上解除异常的方案是毫无优雅可言的,我们可以得出,这里语法糖的所谓擦除,仅仅是对 code属性的字节码进行擦除,实际上元数据还是保留了泛型信息,我们可以通过反射抓取。
严格来说,几乎所有的人类编码,都算是语法糖的体现,只有计算机指令除外。
但是本文为了更好理解语法糖,站的角度略微不同。
在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属性的字节码进行擦除,实际上元数据还是保留了泛型信息,我们可以通过反射抓取。