当前位置: 首页 > news >正文

Java中常见的语法糖

文章目录

    • 概览
    • 泛型
    • 增强for循环
    • 自动装箱与拆箱
    • 字符串拼接
    • 枚举类型
    • 可变参数
    • 内部类
    • try-with-resources
    • Lambda表达式

概览

语法糖是指编程语言中的一种语法结构,它们并不提供新的功能,而是为了让代码更易读、更易写而设计的。语法糖使得某些常见的编程模式或操作变得更加简洁和直观,但在底层实现上,并没有引入新的语言特性或改变语言的表达能力。

尽管语法糖使得代码更加简洁和易读,但实际执行时,底层代码仍然需要遵循编程语言的基本语法和规则。在编译阶段,编译器将使用语法糖编写的高级语法转换为更基础、更原始的语法结构,便于生成相应的目标代码,如字节码或机器码,这就是解语法糖的过程。这个过程确保了最终执行的代码在语义上与原始的语法糖一致,同时能够在目标环境中正确运行。Java编译器的desugar()方法负责这个过程,这个过程确保了Java语言的高级特性可以在不增加JVM复杂性的情况下实现,从而提高了开发效率和代码可读性。

举例来说,假设有如下的Java语法糖:

List<String> list = new ArrayList<>();
list.add("Hello");
String s = list.get(0);

在这段代码中,泛型<String>是语法糖。编译器在编译这段代码时,会将其转换为如下的基础语法:

List list = new ArrayList();
list.add("Hello");
String s = (String) list.get(0);

泛型

泛型允许类、接口和方法在声明时使用参数化类型,提供了编译时类型安全检查机制,避免了强制类型转换的麻烦。但Java中的泛型只在程序源代码中有效,在编译后的字节码中会自动用强制类型转换进行替代。也就是说,Java语言中的泛型机制其实就是一颗语法糖,

// 泛型示例
List<String> names = new ArrayList<>();
names.add("Alice");
String first = names.get(0);
// 解语法糖
List names = new ArrayList();
names.add("Alice");
String first = (String) names.get(0);

增强for循环

增强for循环用于遍历数组或集合,即要么是一个数组,要么实现了Iterable接口,与普通for循环相比,功能更强并且代码更简洁。

public static void main(String[] args) {String[] params = new String[]{"hello","world"};//增强for循环对象为数组for(String str : params){System.out.println(str);}List<String> lists = Arrays.asList("hello","world");//增强for循环对象实现Iterable接口for(String str : lists){System.out.println(str);}
}
// 解语法糖
public static void main(String[] args) {String[] params = new String[]{"hello", "world"};String[] lists = params;int var3 = params.length;//数组形式的增强for退化为普通forfor(int str = 0; str < var3; ++str) {String str1 = lists[str];System.out.println(str1);}List var6 = Arrays.asList(new String[]{"hello", "world"});Iterator var7 = var6.iterator();//实现Iterable接口的增强for使用iterator接口进行遍历while(var7.hasNext()) {String var8 = (String)var7.next();System.out.println(var8);}}

自动装箱与拆箱

自动装箱和自动拆箱是Java中的语法糖,用于简化基本数据类型和其对应包装类型之间的转换操作。当将基本数据类型赋值给对应的包装类型时,编译器会调用包装类型的valueOf()方法来创建一个包装对象,并将基本数据类型的值传递给这个方法。当需要使用包装类型对象中的值进行基本数据类型的操作时,编译器会自动调用包装类型对象的xxxValue()方法,将包装对象转换为对应的基本数据类型值。

Integer boxedNum = 10; // 自动装箱
int num = boxedNum; // 自动拆箱
// 解语法糖
Integer boxedNum = Integer.valueOf(10);
int num = boxedNum.intValue();

字符串拼接

拼接字符串最简单的方式就是直接使用符号"+“来拼接,其实“+”是Java提供的一个语法糖。字符串拼接使用”+"操作符,在编译时会被转换为StringBuilder操作。

String message = "Hello, " + name + "!";
// 解语法糖
StringBuilder sb = new StringBuilder();
sb.append("Hello, ");
sb.append(name);
sb.append("!");
String message = sb.toString();

枚举类型

枚举类型就是一些具有相同特性的类常量,在Java中类的定义使用class,枚举类的定义使用enum。但在Java的字节码结构中,其实并没有枚举类型,枚举类型只是一个语法糖,在编译完成后被编译成一个普通的类。这个类继承java.lang.Enum,并被final关键字修饰。

public enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
// 解语法糖
public final class Day extends Enum<Day> {public static final Day MONDAY = new Day("MONDAY", 0);public static final Day TUESDAY = new Day("TUESDAY", 1);public static final Day WEDNESDAY = new Day("WEDNESDAY", 2);public static final Day THURSDAY = new Day("THURSDAY", 3);public static final Day FRIDAY = new Day("FRIDAY", 4);public static final Day SATURDAY = new Day("SATURDAY", 5);public static final Day SUNDAY = new Day("SUNDAY", 6);private final String name;private final int ordinal;private Day(String name, int ordinal) {this.name = name;this.ordinal = ordinal;}public String name() {return name;}public int ordinal() {return ordinal;}public static Day[] values() {return (Day[]) $VALUES.clone();}public static Day valueOf(String name) {return (Day) Enum.valueOf(Day.class, name);}private static final Day[] $VALUES = {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};
}

可变参数

可变参数就是允许方法接受可变数量的参数。使用变长参数有两个条件,一是变长的那一部分参数具有相同的类型,二是变长参数必须位于方法参数列表的最后面。变长参数同样是Java中的语法糖,其内部实现是Java数组。

public void printNumbers(int... numbers) {}
// 解语法糖
public void printNumbers(int[] numbers) {}

内部类

内部类就是定义在一个类内部的类,之所以引入内部类是因为有些时候一个类只在另一个类中引用,我们不想让其在另外一个地方被使用。内部类可以在一个类内部定义,但在编译时会被转换为独立的类文件,并不是真正套在一个类的内部,而是分成两个类编译。

class Outer {class Inner {void display() {System.out.println("Inner class method");}}
}
// 解语法糖
class Outer {class Inner {final Outer outer;Inner(Outer outer) {this.outer = outer;}void display() {System.out.println("Inner class method");}}
}

try-with-resources

try-with-resources语句简化了资源管理,使得资源在使用后自动关闭,这个语法糖就能让代码及其简洁。原理是编译器把它转换成了try-catch-finally

try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {String line = reader.readLine();System.out.println(line);
} catch (IOException e) {e.printStackTrace();
}
// 解语法糖
BufferedReader reader = null;
try {reader = new BufferedReader(new FileReader("file.txt"));String line = reader.readLine();System.out.println(line);
} catch (IOException e) {e.printStackTrace();
} finally {if (reader != null) {try {reader.close();} catch (IOException ex) {ex.printStackTrace();}}
}

Lambda表达式

Lambda表达式是Java中的一种语法糖,它提供了一种简洁地表示匿名函数的方法,在语法上的简洁性大大提升了代码的可读性和编写效率。在编译后,Lambda表达式会被转换为相应的匿名内部类形式。

Runnable r = () -> System.out.println("Hello, World!");
// 解语法糖
Runnable r = new Runnable() {@Overridepublic void run() {System.out.println("Hello, World!");}
};

相关文章:

  • 昇思25天学习打卡营第02天|张量 Tensor
  • Hive 常见问题
  • 超市管理系统 需求分析与设计 UML 方向
  • cesium 实现地图环境功能 - 雨,雪,雾特效
  • 【Pytorch】数据集的加载和处理(一)
  • lodash将对象转换成http参数
  • Matlab进阶绘图第63期—带标记线的三维填充折线图
  • InterSystems IRIS使用python pyodbc连接 windows环境,odbc驱动安装,DSN配置,数据源配置
  • 科技与狠活
  • elementui 日历组件el-calendar使用总结
  • GESP C++ 三级真题(2023年9月)T1 ⼩ 杨储蓄
  • Ceph资源池pool管理
  • 常用图像分类、目标检测模型性能测试
  • Spring自动装配
  • C# 4.0 等待线程结束
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • [笔记] php常见简单功能及函数
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • CentOS从零开始部署Nodejs项目
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Java程序员幽默爆笑锦集
  • js对象的深浅拷贝
  • js面向对象
  • leetcode388. Longest Absolute File Path
  • Promise面试题,控制异步流程
  • SpingCloudBus整合RabbitMQ
  • SpriteKit 技巧之添加背景图片
  • SSH 免密登录
  • tensorflow学习笔记3——MNIST应用篇
  • Windows Containers 大冒险: 容器网络
  • 对JS继承的一点思考
  • 诡异!React stopPropagation失灵
  • 开发基于以太坊智能合约的DApp
  • 盘点那些不知名却常用的 Git 操作
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 异常机制详解
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # 安徽锐锋科技IDMS系统简介
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #NOIP 2014#Day.2 T3 解方程
  • #宝哥教你#查看jquery绑定的事件函数
  • #微信小程序(布局、渲染层基础知识)
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (1) caustics\
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (C++)八皇后问题
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (不用互三)AI绘画工具应该如何选择
  • (南京观海微电子)——示波器使用介绍
  • (三分钟)速览传统边缘检测算子
  • (四)linux文件内容查看
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验