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
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值