导语: 在很长一段时间里面 Java一直被认为是”低糖“的语言 在解释什么叫低糖语言这前 我们需要先了解一下 语法糖的概念 也称 糖衣语法语法糖(英语:Syntactic sugar)是由英国计算机科学家彼得·兰丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。
举例来说,许多程序语言提供专门的语法来对数组中的元素进行引用和更新。从理论上来讲,一个数组元素的引用涉及到两个参数:数组和下标向量,比如这样的表达式:get_array(Array, vector(i, j))。然而,许多语言支持这样直接引用:Array[i, j]。同理,数组元素的更新涉及到三个参数:set_array(Array, vector(i, j), value),但是很多语言提供直接赋值:Array[i, j] = value

不得不说这种语法糖使得程序的可读性与易用性有了很大提高 那作为编程语言界翘楚的Java编程语言自然也有很多的语法糖存在。

一.Java的语法糖是编写期语法糖

怎么理解 编写期语法糖呢?语法糖的存在主要是方便开发人员使用。但其实,Java虚拟机并不支持这些语法糖。这些语法糖在编译阶段就会被还原成简单的基础语法结构,这个过程就是解语法糖。 看过Java虚拟机源码的都知道 虚拟机执行过程中有一步会去调用 desuger()方法进行解语法糖

二.Java语法糖举例

语法糖其实广泛存在于Java语言中 所以近几年Java是低糖语言的声音已经越来越小了 下面我们就深入Java字节码文件去了解和学习Java语法糖

1.语法糖的应用Ⅰ-Java对泛型的支持

Java本身是一门强类型的编程语言 所以Java虚拟机是不支持泛型的 但是为了方便开发人员使用和减少强制类型转换时的出错概率,Java提供了一种叫 编译期泛型的 Java语法糖 正因为虚拟机中没有泛型,只有普通类和普通方法,所有泛型类的类型参数在编译时都会被擦除,泛型类并没有自己独有的Class类对象。比如并不存在 List <T>.class或是List<Object>.class,而只有List.class

public class SugerTest {public static void main(String[] args) {Map<String,String> items = new HashMap<>();items.put("company","SPD Bank");}
}

反编译之后的代码其实是

public class SugerTest
{public SugerTest(){}public static void main(String args[]){Map items = new HashMap();items.put("company", "SPD Bank");}
}

所以最终的泛型其实是会在编译完成后进行类型擦除的 因为本质上Java是强类型语言 不支持泛类型

了解这个语法糖对我们开发有什么指示和警醒作用呢?虽然Java最终不能支持泛型 但是引入泛型确是非常成功和有必要的 我们都知道 List list=new arrayLIst();虽然这样写很简单 但是代码却很危险 为什么这么说 因为List中虽然可以放入任意元素 但是他们的类型需要一致 例如:

public class SugerTest {public static void main(String[] args) {List item= Lists.newArrayList();int a=1;String b="@";item.add(1);item.add(b);}
}

上述代码其实是有危险的代码 但是由于我们没有使用泛型导致这个潜在性错误在编译器没有被发现 但是一旦程序运行就有可能会出现异常

2.语法糖的应用Ⅱ-swatch对String的支持

在JDK1.7这前String类型是不能在Swatch语句中作为参数使用的 在JDK1.7引入了相应的语法糖支持
我们都知道 swatch语句的参数只能是int类型的值 有人说 swatch不是还支持 char吗 原因很简单 char类型的Asll-Ⅱ码是int类型数值 布尔类型 本质上是 0和1 所以上述类型天生就可以被swatch支持。那么我们如何让String类型也可以在swatch中使用呢?首先我们想到的就是求String的哈希值 所幸hashCode 函数返回值的确是一个int值 那么问题就变得简单了 于是乎在JDK1.7就自然新增了String作为参数的支持了 我们通过字节码文件转换来看看Java语法糖底层是怎么实现swatch对String的支持的

public class SugerTest {public static void main(String[] args) {String week="星期一";switch (week) {case "星期一":break;case "星期二":break;case "星期三":break;case "星期四":break;case "星期五":break;case "星期六":break;case "星期天":break;}}
}

反编译之后的代码 (解语法糖后的代码)

public class SugerTest
{public SugerTest(){}public static void main(String args[]){String week = "\u661F\u671F\u4E00";String s = week;byte byte0 = -1;switch(s.hashCode()){case 25961760: if(s.equals("\u661F\u671F\u4E00"))byte0 = 0;break;case 25961900: if(s.equals("\u661F\u671F\u4E8C"))byte0 = 1;break;case 25961769: if(s.equals("\u661F\u671F\u4E09"))byte0 = 2;break;case 25964027: if(s.equals("\u661F\u671F\u56DB"))byte0 = 3;break;case 25961908: if(s.equals("\u661F\u671F\u4E94"))byte0 = 4;break;case 25962637: if(s.equals("\u661F\u671F\u516D"))byte0 = 5;break;case 25964617: if(s.equals("\u661F\u671F\u5929"))byte0 = 6;break;}switch(byte0){case 0: // '\0'case 1: // '\001'case 2: // '\002'case 3: // '\003'case 4: // '\004'case 5: // '\005'case 6: // '\006'default:return;}}
}

为什么用了hash值还要equals方法呢?原因很简单 hash会存在冲突 就是两个不同的对象他们的hash值可能相同 基于这一点所以我们很有必要调用equals方法确保万无一失

3.语法糖的应用Ⅲ-包装类型的拆箱与装箱

包装类型我想大家并不陌生,其实自动装拆箱操作也是Java语法糖应用之一 在这这前我也专门讲过一篇关于 包装类型的装箱与拆箱的文章 请移步 关于 “Java基本数据类型和它的包装类“ 我想说…

4.语法糖的应用Ⅳ-枚举 本质上就是一种语法糖哦

在枚举类型没有出现这前 Java对常量组的管理还是 写一组常量值然后导出常量 不仅效率低下而且不易于维护和管理 可以说枚举的出现从根本上解决了这个问题 关于枚举的优势实在太多 这边不再进行赘述 因为与本文关系不大
下面我们就写一个最普通的枚举类 去看看 Java语法糖是如何支持枚举类型的

public enum WeekEnum {MONTHDAY("MONTHDAY","星期一"),TuesDay("TuesDay","星期二"),WednesDay("WednesDay","星期三"),ThursDay("ThursDay","星期四"),Friday("Friday","星期五"),Saturday("Saturday","星期六"),Sunday("Sunday","星期天");private String code;private String desc;WeekEnum(String code, String desc) {this.code = code;this.desc = desc;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}
}

反编译之后的代码

public final class WeekEnum extends Enum
{public static WeekEnum[] values(){return (WeekEnum[])$VALUES.clone();}public static WeekEnum valueOf(String name){return (WeekEnum)Enum.valueOf(com/foresee/modules/user/WeekEnum, name);}private WeekEnum(String s, int i, String code, String desc){super(s, i);this.code = code;this.desc = desc;}public String getCode(){return code;}public void setCode(String code){this.code = code;}public String getDesc(){return desc;}public void setDesc(String desc){this.desc = desc;}public static final WeekEnum MONTHDAY;public static final WeekEnum TuesDay;public static final WeekEnum WednesDay;public static final WeekEnum ThursDay;public static final WeekEnum Friday;public static final WeekEnum Saturday;public static final WeekEnum Sunday;private String code;private String desc;private static final WeekEnum $VALUES[];static {MONTHDAY = new WeekEnum("MONTHDAY", 0, "MONTHDAY", "\u661F\u671F\u4E00");TuesDay = new WeekEnum("TuesDay", 1, "TuesDay", "\u661F\u671F\u4E8C");WednesDay = new WeekEnum("WednesDay", 2, "WednesDay", "\u661F\u671F\u4E09");ThursDay = new WeekEnum("ThursDay", 3, "ThursDay", "\u661F\u671F\u56DB");Friday = new WeekEnum("Friday", 4, "Friday", "\u661F\u671F\u4E94");Saturday = new WeekEnum("Saturday", 5, "Saturday", "\u661F\u671F\u516D");Sunday = new WeekEnum("Sunday", 6, "Sunday", "\u661F\u671F\u5929");$VALUES = (new WeekEnum[] {MONTHDAY, TuesDay, WednesDay, ThursDay, Friday, Saturday, Sunday});}
}

你会发现本质上枚举也是一个类 上述是解语法糖之后的代码

总结:Java语法糖有很多很多 例如还有变长参数 ,条件编译,等等等等 由于篇幅关系不能一一举例 总之一点 Java语法糖的存在是为了方便程序开发人员的 它的存在能大大减少开发成本并且能够让使用者更加容易的理解程序开发

Java真的是低糖语言吗?相关推荐

  1. 阿里云面试:什么是语法糖?Java中有哪些语法糖?

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  2. 什么是语法糖?Java中有哪些语法糖?

    本文从 Java 编译原理角度,深入字节码及 class 文件,抽丝剥茧,了解 Java 中的语法糖原理及用法,帮助大家在学会如何使用 Java 语法糖的同时,了解这些语法糖背后的原理 1 语法糖 语 ...

  3. Java真的是一门编译型的语言吗——即时编译器JIT

    Java真的是一门编译型的语言吗--即时编译器JIT 如有错误请大佬指正 JIT是什么 JIT(Just-in-Time,实时编译)一直是Java语言的灵魂特性之一. 让我们回忆一下Java程序是如何 ...

  4. 浅析java中的语法糖

    概述 编译器是一种计算机程序, 它主要的目的是将便于人编写.阅读.维护的高级计算机语言所写的源代码程序, 翻译为计算机能解读.运行的低阶机器语言的程序, 即可执行文件.而 javac 就是java语言 ...

  5. 从最新的编程语言排行看,Java真的要凉了吗?

    作为一个历经无数风雨的编程语言,Java近些年好像拿到了悲惨的"人设剧本",网络上对它的质疑越来越高,例如: "Java真的要凉了吗?" "Pytho ...

  6. .net门槛是否真的很低?

    .net门槛是否真的很低?最近博客上一直在关于这个问题争论. 首先本人做.NET开发5年,主要从事WINFORM相关开发,包括GIS,数据库等信息系统的开发,另外闲暇时间接点私活做做,写了几个开源的C ...

  7. Java中的低GC:使用原语而不是包装器

    总览 有两个很好的理由在可能的地方使用原语而不是包装器. 明晰. 通过使用原语,您可以清楚地知道null值是不合适的. 性能. 使用原语通常更快. 清晰度通常比性能更重要,并且是使用它们的最佳理由. ...

  8. java zip解压_Java语言入门第一课

    Java最初的目标是嵌入式设备,不过在嵌入式设备方面并未取得成功.失之东隅,收之桑榆,Java却在Web领域被广泛接受.近年来,随着Java在服务器领域的不断突破,让这门语言越来越流行. 有人喜欢Ja ...

  9. 指针的理解 -- java程序员学C语言日记二

    这两个星期内都是在忙公司的事情,所以没有什么时间看C语言,OK,这几天,自己就发现了C语言中指针这个东西,以前看书觉得就只不过是一4个字节的,用于存放了某对象的地址而已,同时可以用这个地址加加减减.. ...

  10. 学习纯软件开发(如Java/Python...)还是C语言、嵌入式、物联网呢?

    我国科技的迅速发展带动了计算机行业的兴盛发展,越来越多的学生,在职人士以及想要提升自己的人群都想学习这一行,给自己的美好未来打好物质基础,有得人想要学习纯软件开发比如Java/Python...,有的 ...

最新文章

  1. 你以为border-radius只是圆角吗?【各种角度】
  2. React Native学习笔记-1:JSC profiler is not supported.(转载)
  3. DayDayUp:本博主预计2019下半年将会出两本书(关于人工智能算法及其实战案例应用方向、计算机算法竞赛集锦方向),如有合作意向,请留言告知
  4. 信安考友分享:软考信息安全工程师备考四年,终成正果
  5. python自带的库有哪些餐厅_Python 常用的标准库以及第三方库有哪些
  6. Flink读取Kafka报错:KafkaException ByteArrayDeserializer is not an instance Deserializer
  7. 正在更新office,应用程序无法正常启动
  8. JDBC-通过Driver接口获取数据库连接
  9. 认知之经济学:经济是如何运行的
  10. 沉默内向的计算机保研er在保研面试中会吃亏吗?
  11. amx-104 r-java_AMX-104 R·贾贾
  12. 关于终止多个for select循环嵌套的问题
  13. OpenAI发布ChatGPT:程序员瞬间不淡定了
  14. 汉明码纠错java_汉明码(Hamming)编码与纠错原理
  15. 怎么在苹果手机计算机上打字,苹果手机怎样设置打字是中文的
  16. 如何让cmd全屏显示?
  17. matlab图注的上标和下标,关于matlab中特殊字符, 上标和下标
  18. HTML5期末大作业:个人主页网站设计(6页)代码质量高 学生简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载
  19. 2021年中国工业品电商行业发展回顾及大型国有工业品电商平台助力民企转型发展的作用分析[图]
  20. Adam优化器简单理解

热门文章

  1. 突变瀑布图及亚型突变瀑布
  2. 撸完这篇线程池,我快咳血了!
  3. Python入门(二) part1 列表
  4. Python-集合练习(协助学生做问卷调查)
  5. Quorum简介部署
  6. python ffmpeg模块_python 模块之-ffmpeg 中文参数对照表
  7. python实现12306查询火车票
  8. Matlab 向量的处理
  9. ERP是什么管理系统?
  10. 小学一年级语文心田花开各类词汇用法汇总