笔记-Java基础之语法糖的味道

泛型与类型擦除

    泛型是JDK1.5的一项新增特性,他的本质是参数化类型(Parametersized Type)的应用,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口和泛型方法。

    泛型技术在C#和Java之中的使用方式看似相同,但实现上却有着根本性的分歧,C#里面泛型无论在程序源码中、编译后的IL中(Intermediate Language,中间语言,这时候泛型是一个占位符),或是运行期的CLR中,都是切实存在的,List<int>与List<String>>就是两个不同的类型,他们在系统运行期生成,有自己的需方发表和类型数据,这种实现称为类型膨胀,基于这种方法实现的泛型称为真是泛型。

    Java语言中的泛型则不一样,它只是在程序源码中存在,在编译后的字节码文件中,就已经替换为原来的原生类型(Raw Type,也称为裸类型)了,并且在相应的地方插入了强制转换代码,因此对于运行期的Java语言来说ArrayList<int>与ArrayList<String>就是同一个类,所以泛型技术实际上是Java语言的一颗语法糖,Java语言中的泛型实现称为类型擦除,基于这种方法实现的泛型称为伪泛型。

    

上面的这段代码是不能被编译通过的,因为参数List<String>和List<Integer>编译之后都被擦除了,变成了一样的原生类型List<E>,擦除动作导致这两种方法的特征签名变得一模一样。

 

    重载当然不是根据返回值来确定的,这段代码和上面的代码的差别是两个method方法添加了不同的返回值,由于这两个返回值的加入,方法重载居然成功了,既这段代码可以被编译和执行了。之所以这次能编译和执行成功,是因为两个method方法加入了不同的返回值才能共存一个Class文件之中。前文介绍Class文件犯法表的数据结构时曾经提到过,方法重载要求方法具备不同的特征签名,返回值并不包含在方法的特征签名之中,所以返回值不参与重载选择,但是在Class文件格式之中,只要描述符不是完全一致的两个方法就可以共存,也就是说,两个方法如果有相同的名称和特征签名,但返回值不同,那他们也是可以合法地共存于一个Class文件中的

    由于Java泛型的引入,JCP组织对虚拟机规范作出了相应的修改,引入了Signature、LocalVariableTypeTable等新的属性用于解决伴随泛型而来的参数类型的识别问题,Signature是其中最重要的一项属性,它的作用就是存储一个方法在字节码层面的特征签名,特性签名最重要的任务就是作为方法独一无二且不可重复的ID,在Java代码中的方法特征签名只包括了方法名称,参数顺序及参数类型、而在字节码中的特征签名还包括方法返回值以及受查异常表。

   从Signature属性的出现我们还可以得出结论,擦除法所谓的擦除,仅仅是对方法的Code属性中的字节码进行擦除,实际上元数据中还是保留了泛型信息,这也是我们能通过反射手段获得参数化类型的根本依据。

自动装箱、拆箱与遍历循环

    毫无疑问,他们是Java语言里使用地最多的语法糖。自动装箱、拆箱在编译之后被转化成了对应的包装和还原方法。例如Integer.valueOf()与Integer.intValue()方法,而便利循环则吧代码还原成了迭代器的实现,这也是为何遍历循环需要被便利的类实现Iterable接口 

条件编译

    Java语言当然也可以进行条件编译,方法就是使用条件为常量的if语句。如下代码所示:

    此代码中的if语句不同于其他Java代码,它在编译阶段就会被“运行”,生成的字节码之中只包括“System.out.printIn("block 1”);"一条语句,并不会包含if语句及另外一个分支中的"System.out.printIn("block2");。

    只能使用条件为常量的if语句才能达到上述效果,如果使用常量与其他带有条件判断能力的语句搭配,则可能在控制流分析中提示错误,被拒绝编译。

Java语言中条件编译的实现,也是Java语言的一刻语法糖,根据布尔常量值的真假,编译器将会把分支中不成立的代码块消除掉。这一工作将在编译器解除语法糖阶段(com.sun.tools.javac.comp.Lower类中)完成。由于这种条件编译的实现方式使用了if语句,所以它必须遵循最基本的Java语法,只能写在方法体内部,因此它只能实现基本块(Block)级别的条件编译,而没哟与办法根据条件调整整个Java类的结构。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值