java语法糖

switch 支持 String 与枚举

在开始coding之前先科普下,Java中的swith自身原本就支持基本类型。比如int、char等。

对于int类型,直接进行数值的比较。对于char类型则是比较其ascii码。

所以,对于编译器来说,switch中其实只能使用整型,任何类型的比较都要转换成整型。比如byte。short,char(ackii码是整型)以及int
那么接下来看下switch对String得支持,有以下代码:
在这里插入图片描述
反编译后内容如下:
在这里插入图片描述
仔细看下可以发现,进行switch的实际是哈希值,然后通过使用equals方法比较进行安全检查,这个检查是必要的,因为哈希可能会发生碰撞。因此它的性能是不如使用枚举进行switch或者使用纯整数常量,但这也不是很差

泛型

泛型,即“参数化类型”,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),
然后在使用/调用时传入具体的类型(类型实参)。
类型擦除的主要过程如下:
1.将所有的泛型参数用其最左边界(最顶级的父类型)类型替换。
2.移除所有的类型参数
以下代码:
在这里插入图片描述
解语法糖之后会变成:
在这里插入图片描述

自动装箱与拆箱

自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱
先来看个自动装箱的代码
在这里插入图片描述
反编译后代码如下:
在这里插入图片描述
再来看个自动拆箱的代码
在这里插入图片描述
包装类与基本数据类型进行比较运算,是先将包装类进行拆箱成基本数据类型,然后进行比较的
说明:对于 Integer var = ? 在-128 至 127 范围内的赋值,Integer 对象是在 IntegerCache.cache 产 生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数 据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断
在这里插入图片描述

反编译后代码如下
在这里插入图片描述

方法变长参数

它允许一个方法把任意数量的值作为参数
在这里插入图片描述
反编译后代码:
在这里插入图片描述
从反编译后代码可以看出,可变参数在被使用的时候,他首先会创建一个数组,数组的长度就是调用该方法是传递的实参的个数,然后再把参数值全部放到这个数组当中,然后再把这个数组作为参数传递到被调用的方法中

内部类

java8开始,内部类使用外部变量,不再需要外部变量修饰为final了。然后,内部类使用的外部变量,还是要求:外部变量要么是final的,要么自初始化后值不会被改变 。否则编译报错:error: local variables referenced from an inner class must be final or effectively final

原理

对于final的外部变量。在编译之后,会存储到常量池中,匿名内部类使用到该常量的地方都会被替换为对应的“常量值”,比如使用了外部的String str = “java” , 匿名内部类所有用到str的地方都会被替换为”java” 。这样一来,从字节码级别看,内部类引用外部变量的痕迹被抹得一干二净
对于非final的外部变量。匿名内部类在编译后,会自动生成构造函数,并且,外部对象以及外部参数会作为参数传递进来。对于基本类型,传递的值是拷贝;对于对象类型,传递的是引用。因此在内部类中对该外部变量的“值”修改是无效的;另外,如果外部变量在外部类中有修改,那么内部类使用该变量时可能值已经不是预期的那个“值”了。所以内部类使用的外部变量,不允许有任何的修改才能避免上述问题-

for-each

for-each的实现原理其实就是使用了普通的for循环和迭代器
在这里插入图片描述
在这里插入图片描述

try-with-resource

在这里插入图片描述
反编译以上代码,看下他的背后原理
其实也是try catch finally,在finally里关闭

if

其实下面的语句编译之后,还是会加上else

if(x>1){
return 1;
}
return 2

问题

增强for循环
在这里插入图片描述
Iterator是工作在一个独立的线程中,并且拥有一个 mutex 锁。Iterator被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出java.util.ConcurrentModificationException异常。

所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法remove()来删除对象,Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java语法糖是指Java语言中为了更方便开发者使用而提供的一些特性,这些特性本质上并不会改变Java语言的运行机制,而是通过编译器或运行时库等方式将这些语法糖转换为Java语言本身能够识别的代码。这些语法糖的目的是为了简化代码的写法,让代码更易于理解和维护。 一些典型的Java语法糖包括: - 自动装箱与拆箱:可以在Java代码中直接使用基本数据类型,而无需手动创建对应的包装类对象。 - for-each循环:可以直接遍历数组或集合中的所有元素,而无需使用下标或迭代器。 - 可变参数列表:可以将一组参数封装为数组传递给方法,而无需手动创建数组。 - Lambda表达式:可以创建简单的匿名函数,而无需定义单独的函数对象。 这些语法糖都是在编译期间转换为Java语言本身的特性,因此不会对程序的性能造成影响。 ### 回答2: Java语法糖是指在Java编程语言中的一些语法上的改进和简化,它使得代码更加易读、简洁和易于理解。语法糖不是新增加的语言功能,而是对现有功能的语法上的改良。 一个常见的Java语法糖是自动装箱和拆箱。在Java 1.5之前,基本类型(如int、float等)和它们对应的包装类(如Integer、Float等)之间不能直接进行赋值或比较操作,需要通过手动装箱和拆箱的方式。但通过语法糖的改进,现在可以直接在基本类型和对应的包装类之间进行自动转换,使得代码更加简洁和优雅。 另一个例子是增强的for循环。在Java 1.5之前,遍历数组或集合需要使用传统的for循环,并且需要手动获取和指定迭代器。而通过语法糖的改进,现在可以使用更加简洁的增强的for循环,将原始的方法调用、初始化和变量声明过程都隐藏在背后,使得代码更加易读和简洁。 还有一些其他的语法糖,如可变参数、枚举类型、Lambda表达式等,它们都是通过简化和优化语法上的表示方式,提高代码的可读性和可维护性。 需要注意的是,尽管语法糖使得代码更加简洁,但底层执行的逻辑并没有改变。编译器会将语法糖转换为等价的原始代码,然后再进行编译和执行。所以在阅读和理解代码时,还是需要了解底层的语言特性和实现细节。 ### 回答3: Java语法糖是一种语法的简化形式,它能够使得代码更加易读易写,并且不会增加程序的运行效率。 在Java语言中,有些常见的操作会使用较为繁琐的语法去实现,为了简化这些操作的写法,Java引入了语法糖语法糖并不是一种新的特性或者语法规则,而是一种编译器提供的功能,可以将一些常见的代码模式转化为更简洁的语法结构。 常见的Java语法糖包括自动拆装箱、泛型、枚举类型、增强的for循环以及可变参数等。通过使用这些语法糖,可以使得代码更加简洁易读,并且减少了一些常见错误的发生。 比如,自动拆装箱允许我们在基本类型和包装类型之间进行自动的转换,不需要手动进行转换操作。使用泛型可以在编译时进行类型检查,避免了类型转换的错误。枚举类型提供了更好的可读性和类型安全性。增强的for循环可以简化对数组和集合的迭代操作。可变参数允许我们以更方便的方式传递不定数量的参数。 尽管语法糖提供了更加简洁的写法,但是在编译过程中,这些语法糖都会被转化为等价的标准Java代码,所以对于程序的运行效率没有实质的影响。 总的来说,Java语法糖使得代码更加易读易写,并且减少了一些常见错误的发生,提高了程序的可维护性和开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值