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属性的字节码进行擦除,实际上元数据还是保留了泛型信息,我们可以通过反射抓取。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

annan211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值