java语法糖一些简要心得(含有类型擦除和拆箱和装箱)

 

什么叫语法糖?

语法糖既是指在计算机语言中添加某种语法,这个语法本生对程序来说并没有什么坏处,只是方便程序的开发,说白了语法糖就是对现有语法的一种封装。再直白一点来说就是用这个语言本身的语法封装一大段的代码之后然后再上层使用的时候只需要用一个简单的操作就可以完成一系列浮躁的操作,而这些操作开发者可能并不知道他最终是如何使用语法糖衣的。

java中的语法糖(基于java1.7):

泛型

自动装箱和拆箱

枚举

内部类

长循环遍历

变长参数

try语句使用资源

断言

switch的字符串支持

泛型与类型擦除:

Java语言并不是一开始就支持泛型的。在早期的JDK中,只能通过Object类是所有类型的父类和强制类型转换来实现泛型的功能。强制类型转换的缺点就是把编译期间的问题延迟到运行时,JVM并不能为我们提供编译期间的检查。

在JDK1.5中,Java语言引入了泛型机制。但是这种泛型机制是通过类型擦除来实现的,即Java中的泛型只在程序源代码中有效(源代码阶段提供类型检查),在编译后的字节码中自动用强制类型转换进行替代。也就是说,Java语言中的泛型机制其实就是一颗语法糖,相较与C++、C#相比,其泛型实现实在是不那么优雅。

但是Java的泛型和C++/C#的泛型本质上是不一样的,C++/C#的泛型是一个占位符,在运行期都是存在的,比如List<Integer>List<String>是不同的类型,在运行期都有自己的虚方法表和类型数据,这种实现才是真正的泛型,但是在Java里,泛型就是一个语法糖,只是在源码内存在,在编译后的字节码文件中,就已经替换为原来的原生类型(Object)了,也就是说在运行期中,List<Integer>List<String>在运行期就变成了List<Object>List<Object>,就是相同的类型,这种泛型就是伪泛型了,这种也是泛型擦除。

public class test{
public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hello", "沃德");
        System.out.println(map.get("hello"));
    }
}

 

反编译后的代码:

public class test{
    public static void main(String[] var0) {
      HashMap var1 = new HashMap();
      var1.put("hello", "沃德");
      System.out.println((String)var1.get("hello"));
   }
}

可以看到泛型被擦除且引入强制类型转换,这样做的目的存在一定的缺点,应为进行类型转换会对性能有一定的影响

自动装箱和拆箱:

什么叫做自动拆箱和装箱?

我们都知道java中出了基本的数据类型还有一些这些基本数据类型的包装类,比如Interger等当使用语法糖之后就可以对这些基本类型和包装类型进行拆箱(使用Integer.intValue())和装箱(使用Interger.valueOf()),这样就很方便了比如你定义一个包装类的int,那就可以使用下面的语法来定义,在反编译后他就会自动装箱将i包装成Interger的类型,使用的时候拆箱就行了。

Interger i=10;

 

来看一个典型的例子:

public class Main {

    public static void main(String[] args) { 

        Integer a = 1;

        Integer b = 2;

        Integer c = 3;

        Integer d = 3;

        Integer e = 321;

        Integer f = 321;

        Long g = 3L;

        Long h = 2L;         

        System.out.println(c==d);

        System.out.println(e==f);

        System.out.println(c==(a+b));

        System.out.println(c.equals(a+b));

        System.out.println(g==(a+b));

        System.out.println(g.equals(a+b));

        System.out.println(g.equals(a+h));

    }

}

先别看输出结果,读者自己想一下这段代码的输出结果是什么。这里面需要注意的是:当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。另外,对于包装器类型,equals方法并不会进行类型转换。明白了这2点之后,上面的输出结果便一目了然:

true
false
true
true
true
false
true

 

  第一个和第二个输出结果没有什么疑问。第三句由于  a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等。而对于c.equals(a+b)会先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。同理对于后面的也是这样,不过要注意倒数第二个和最后一个输出的结果(如果数值是int类型的,装箱过程调用的是Integer.valueOf;如果是long类型的,装箱调用的Long.valueOf方法)。

后面的就不一一总结了,有兴趣的同学可以使用自己时间验证一下,写一段代码然后反编译一下就可以看到。

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值