目录
(一)泛型与类型擦除
(二)自动装箱和拆箱
(三)foreach循环
(四)变长参数
(五)条件编译
(六)内部类
(七)枚举类和switch
(八)断言语句
(九)总结
首页 Java java教程 java糖衣语法(Syntactic Sugar)详解

java糖衣语法(Syntactic Sugar)详解

Mar 01, 2017 pm 01:19 PM


糖衣语法,也叫做语法糖。最开始是英国计算机学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语。语法糖是指某一类语法,这类语法通过一些简单的包装,让代码变得简洁、可读性好,并在编译时通过“解语法糖”的方式,在功能不变的情况下用简单语法来通过编译。
正如其名,语法糖就像是一层糖衣,通过这层糖衣让代码变得简洁。虚拟机并不支持这类语法,在虚拟机运行之前,这类语法就会被编译成更通俗的简单的语法,但功能不变。
在java中,常用的语法糖有以下这些:

  1. 泛型与类型擦除

  2. 自动装箱和拆箱

  3. foreach循环

  4. 变长参数

  5. 条件编译

  6. 内部类

  7. 枚举类和switch

  8. 断言语句

下面我们就一个个的来分别看一下每个语法糖的功能用法和他实际的原理

(一)泛型与类型擦除

在java的虚拟机中没有泛型类,每一个类型在java虚拟机中都有一个相对应的基本类型。下面是一篇泛型及原理的解析。

泛型类详解传送门:http://www.php.cn/java-article-354231.html

(二)自动装箱和拆箱

在java代码中,很多时候我们不能直接使用八个基本类型,而是要使用他们对应的包装类(也叫包装器 wrapper)这些对象包装类的名字也很容易记忆:Integer、Long、Byte、Double、Float、Character、Boolean、Short。最简单的例子就是泛型中,因为擦除后无法将基本类型存入Object中,所以必须使用包装类作为类型参数:

List<int> list = new ArrayList<>();//errorList<Integer> list = new ArrayList<>();//ok
登录后复制

自动装箱过程:把基本类型用它们对应的包装类型进行包装,使基本类型具有对象特征。
自动拆箱过程:与装箱过程相反,把包装类型转换成基本类型。

通俗地讲,装箱和拆箱就是方便了程序员在包装类和基本类之间的转换,少写了几句话,简洁了代码,有的时候代码里多出一句这样类型的转化确实有煞风景,自动装箱和拆箱优势是显而易见的。

List<Integer> list = new ArrayList<>();list.add(1);list.add(Integer.valueOf(1));//实际操作 自动装箱int n = list.get(0);
int m = list.get(0).intValue();//实际操作 自动拆箱Integer p = 1;
p++; //实际插入一句拆箱,再自增计算,再装箱
登录后复制

在Integer等包装类中,数值间的比较需要用equals方法,否则比较的是两个对象的地址是否储存于同一区域。用==来比较,根据被包装到的对象情况,结果是true和false都有可能的。

Integer a = 1000;Integer b = 1000;System.out.println(a==b); 
// 输出:falseSystem.out.println(a.equals(b)); //输出:true
登录后复制

值得一提的是,包装类也是放置类型转换这类静态方法的好地方:

int x =Integer.parseInt("111"); // x=111
登录后复制

(三)foreach循环

java中提供了一个超级简洁的循环方法,foreach循环。作为一种没有索引的循环方式,foreach循环只能遍历全部的元素而不具有选择性,但是简单的写法还是方便了很多,在HashMap这种毫无索引的数据结构中,foreach循环相比for循环和while循环好的多。那么,foreach循环是用什么来实现的呢?答案就是迭代器Iterator。

for(int i : list){
    System.out.println(i);
}

//实际迭代器实现for (Iterator localIterator = list.iterator(); localIterator.hasNext(); ) { 
    int sub = ((Integer)localIterator.next()).intValue(); 
    System.out.println(sub);}
登录后复制

遍历所有的元素是用Iterator来实现的这点是容易想出来的,但是实际上的代码量确实比foreach循环增加了不少,语法糖起到了方便代码的作用,功不可没。

(四)变长参数

在java1.5之后,提供了一种可变参数的方法调用,打破了参数只能是固定数量的尴尬局面。说起来玄,但是变长参数的方法我们在日常中几乎天天用,比如字符串的格式化:

public void foo(String str,Object...args){...}//方法原型

System.out.printf("%d",1);
System.out.printf("%d,%s", 12,"a");//方法中的变长参数必须位于最后一个位置
登录后复制

变长参数的实质是把这个位于最后一位变长参数换做Object[],换来换去都是一样的内容。

(五)条件编译

条件编译是Java虚拟机对代码进行了简化,它根据布尔常量的真假,去掉了分支不正确的代码块。只有使用条件为常量的If语句才能达到这种的效果。这一条也是容易理解的。

if(true)  
{  
    System.out.println("true");  
}  
else {  
    System.out.println("false");  
}  
//实际条件编译System.out.println("true");
登录后复制

(六)内部类

虚拟机中没有内部类,所有的内部类都通过一定的方法变成了普通类。

内部类详解传送门:http://www.php.cn/java-article-354230.html

(七)枚举类和switch

在java之中也存在着类似c++的枚举类型,但是客观上并没有c++中的好用。枚举类型可以包括有限个命名的值,并且可以声明这种类型其中的变量:

package Syntactic;public enum Size {
    S,M,L,XL
}

Size s = Size.S; //声明一个s,值为枚举类型中的S
登录后复制

枚举类也是一种语法糖,在虚拟机中并没有枚举类,JVM也不认识它。首先,所有的枚举类都是继承于java.lang.Enum类。在编译时编译器会把枚举类直接变成实在的Enum的子类。枚举类中的每一个值都会通过构造器变为实例。

//构造器protected Enum(String name, int ordinal) {...}
//第一个参数为枚举值,第二个参数为这个枚举值默认的顺序
//下面是在编译时,实际操作的将枚举值实例化的过程
new Enum<Size>("S",0);new Enum<Size>("M",1);
new Enum<Size>("L",2);new Enum<Size>("XL",3);
登录后复制

与此同时,既然枚举类型是语法糖,那么也就有switch用枚举值作为判断,也是一种语法糖。既然枚举类型是语法糖,在虚拟机中并不存在这种语法,switch中的枚举自然也是语法糖,那么它的原理是什么呢?

首先我们要分析一下switch能够用什么来判断。1.char、byte、int、short类型,2.枚举类型,3.字符串字面量。在这些之中一定有一种类型是枚举类型实际采用的判断方式。实际上,枚举类型采用的判断方式是int(short)类型。我们刚才说过,在每个枚举类型实例化的过程中都会贴上一个顺序的序号的“标签”。new Enum<Size>("S",0)在编译的过程中,编译器把这个序号作为他们的标记来替换switch中的枚举类型。

(八)断言语句

断言语句是在java的测试阶段普遍使用的一种语句,在1.4版本发布,而其本身也是一种语法糖。

(九)总结

在java中有很多糖衣语法,这些语法在不改变功能的情况下方便了我们的工作,提高了我们的效率。对于这些语法的内部实际处理虽然不一定用得到,但是有些了解还是很好的。语法糖是指那种在虚拟机中不存在但是我们可以这样编写代码的语法,并不一定只有上述的几种,但是上述是其中较为常用的。

 以上就是java糖衣语法(Syntactic Sugar)详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

Java 中的时间戳至今 Java 中的时间戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的时间戳到日期指南。这里我们还结合示例讨论了介绍以及如何在java中将时间戳转换为日期。

Java程序查找胶囊的体积 Java程序查找胶囊的体积 Feb 07, 2025 am 11:37 AM

胶囊是一种三维几何图形,由一个圆柱体和两端各一个半球体组成。胶囊的体积可以通过将圆柱体的体积和两端半球体的体积相加来计算。本教程将讨论如何使用不同的方法在Java中计算给定胶囊的体积。 胶囊体积公式 胶囊体积的公式如下: 胶囊体积 = 圆柱体体积 两个半球体体积 其中, r: 半球体的半径。 h: 圆柱体的高度(不包括半球体)。 例子 1 输入 半径 = 5 单位 高度 = 10 单位 输出 体积 = 1570.8 立方单位 解释 使用公式计算体积: 体积 = π × r2 × h (4

如何在Spring Tool Suite中运行第一个春季启动应用程序? 如何在Spring Tool Suite中运行第一个春季启动应用程序? Feb 07, 2025 pm 12:11 PM

Spring Boot简化了可靠,可扩展和生产就绪的Java应用的创建,从而彻底改变了Java开发。 它的“惯例惯例”方法(春季生态系统固有的惯例),最小化手动设置

See all articles