相信很多小伙伴多多少少都听说过Java语法糖的内容,下面我将为大家简单地介绍一下Java中语法糖的基本内容,Java有哪一些语法糖及其具体的使用方法,还有Javajdk迭代相关的一些新特性。
语法糖(Syntactic sugar)
是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
糖1:for-each
功能和传统的fori相似
代码样例
public class Test {
public static void main(String[] args) {
int[] num = new int[10];
for (int i = 0; i < 10; i++) {
num[i] = i;
}
//旧版本
for (int i = 0; i < num.length; i++) {
System.out.print(num[i]+" ");
}
System.out.println();
//新版本
for (int i:num) {
System.out.print(num[i]+" ");
}
}
}
输出对比
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
特性
- for-each从JDK5.0开始引入
- for-each语法更加简洁
- for-each可以避免语法越界错误
- fori可以删除元素,for-each不可以
- for-each遍历时候不知道当前元素的具体位置
- for-each只能正向遍历,不能反向遍历
- for-each不能同时遍历两个集合
糖2:枚举类型
变量的取值只在一个有限的集合里面
代码样例
public class Test {
public static void main(String[] args) {
enum Size{
SMALL,MEDIUM,LARGE;
}
Size s1 = Size.SMALL;
Size s2 = Size.MEDIUM;
Size s3 = Size.LARGE;
Size s4 = Size.SMALL;
System.out.println(s1==s4);
System.out.println(s3==s4);
}
}
输出样例
true
false
特性
- enum声明枚举类,且都是Enum的 子类
- enum内部有多少个值,就有多少个实例对象
- 不能直接new枚举类对象
- 除了枚举的内容 ,还可以添加属性,方法 ,构造函数
- 构造函数只能是private类型,只能内部调用
- enum也继承了Enum的子类,也继承了相应方法
- ordinal()返回枚举值所在的索引位置
- compareTo()比较两个枚举值的索引位置大小
- toString()放回枚举值的字符串表示
- valueOf()将字符串初始化为枚举对象
- values()返回所有的枚举值
糖3:不定项参数
普通函数的形参列表是固定个数/类型/顺序
JDK5.0提供了不定项参数(可变参数)功能
代码样例
public class Test {
public static void main(String[] args) {
test("aaa");
test("aaa","bbb","ccc");
}
public static void test(String... args){
System.out.println(args.length);
for (String arg:args) {
System.out.println(arg);
}
}
}
输出样例
1
aaa
3
aaa
bbb
ccc
特性
- 类型后面加…表示,如代码样例所示
- 可变参数,实际上是一个数组
- 一个方法只能有一个不定项参数,且必须位于参数列表的最后
- 优先规则1:固定参数的方法比可变参数优先级更高
- 优先规则2:调用语句,同时与两个带可变参数的方法匹配,则报错
糖4:静态导入
import导入程序所需要的类
import static导入一个类的静态方法和静态常量(JDK5.0引入)
代码样例
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
import static java.lang.System.out;
public class Test {
public static void main(String[] args) {
int a=3,b=4,c=0;
//静态引入
c = (int) sqrt(pow(a,2)+pow(b,2));
//原本用法
c = (int) Math.sqrt(Math.pow(a,2)+Math.pow(b,2));
//静态引入
out.println(c);
//原本用法
System.out.println(c);
}
}
输出样例
5
5
特性
- 可以省略类名,直接用
- 静态方法具有明确特征,如有重名,需要补充类名
- 通配符:*
糖5:自动装箱和拆箱
在java中,基本类型放在栈里面,对象则是在堆里开辟了内存空间,把对象的引用存入栈里面,基本类型可以包含在对象里面,所以形象的形容为装箱
从JDK5.0开始引入,简化了基本类型和对象转化的写法
基本类型:boolean/byte/char/int/short/long/float/double
对象:Boolean/Byte/Character/Integer/Short/Long/Float/Double
代码样例
public class Test {
public static void main(String[] args) {
//自动装箱
Integer obj1 = 5;
//原始用法
Integer obj2 = Integer.valueOf(5);
//自动拆箱
int a1 = obj1;
//原始用法
int a2 = obj2.intValue();
System.out.println(obj1);
System.out.println(a1);
System.out.println(obj2);
System.out.println(a2);
}
}
输出样例
5
5
5
5
特性
- 装箱和拆箱都是编译器的工作,在class中已经添加转化,虚拟机中没有自动拆箱和装箱的语句
- 对于==:基本类型是内容相同,对象是指针是否相同(内存同一个区域)
- 基本类型没有空值,对象有null,可能引发NullPointerException
- 当一个基础数据类型与封装类型进行==,+,-,*,/运算时,会将封装类进行拆箱,对基本数据类型进行运算
- 谨慎使用多个非同类的数值类对象进行运算
糖6:多异常并列
多个异常并列在一个catch中
从JDK7.0Y引入,简化写法
代码样例
import java.io.IOException;
import java.sql.SQLException;
public class Test {
public static void main(String[] args) {
//旧版本
try {
test();
}
catch (IOException ex){
//异常处理
}
catch (SQLException ex){
//异常处理
}
//新版本
try {
test();
}
catch (IOException | SQLException ex){
//异常处理
}
}
private static void test() {
}
}
特性
- 并列的特性不能直接有或间接有继承关系,如果有,则报错
糖7:整数类型用二进制赋值
从JDK7.0开始引入
整数类型可以用二进制进行赋值
代码样例
public class Test {
public static void main(String[] args) {
byte a1 = (byte) 0b00100001;
short a2 = (short) 0b10101010101;
int a3 = 0b101;
long a4 = 0b101010101011011011010101011L;
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
System.out.println(a4);
}
}
输出样例
33
1365
5
89503403
特性
- 避免二进制计算
- 0b表示二进制数
糖8:数字中的下划线
从JDK7.0开始引入
在数字字面量中使用下划线
代码样例
public class Test {
public static void main(String[] args) {
//二进制,0b开头
int a1 = 0b0100_1011_0001;
//八进制,0开头
int a2 = 02_014;
int a3 = 123__45;
//十六进制,0x开头
int a4 = 0x7_567;
float a5 = 3.56_78f;
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
System.out.println(a4);
System.out.println(a5);
}
}
输出样例
1201
1036
12345
30055
3.5678
特性
- 增加数字的可读性和纠错功能
- 下划线只能出现在数字中间,前后必须有数字
- 下划线不能拆开0x
- 允许在二/八/十/十六进制中使用
- 可以使用多个下划线
糖9:接口的默认方法
java最初的设计中,接口的方法都是没有实现的公开的
JDK8.0推出接口的默认方法/静态方法(都带实现的),为Lambda表达式提供支持
代码样例
public class Test {
public interface Animal{
public void move();
}
public interface NewAnimal{
public default void move(){
System.out.println("I can move");
};
}
}
特性
- 用default关键字标注,其他的定义和普通函数一样
- 默认方法不能重写Object中的方法
- 实现类可以继承/重新父接口的默认方法
- 接口可以继承/重新父接口的默认方法
- 当父类和父接口都有同名同参数的默认方法的时候,子类继承父类的默认方法,这样可以兼容JDK7.0以前的代码
- 子类实现了两个接口(同名同参),那么编译失败,必须在子类中重写这个default方法
糖10:接口的静态方法
JDK8.0推出带实现的静态方法
代码样例
public class Test {
public interface StaticAnimal{
public static void move(){
System.out.println("I can move");
}
}
public interface StaticLandAnimal extends StaticAnimal{
//继承不到StaticAnimal的move方法
}
public static void main(String[] args) {
//正确引用
StaticAnimal.move();
//错误引用
StaticLandAnimal.move();
new StaticAnimal().move();
}
}
特性
- 该静态方法属于本接口,不属于子类/子接口
- 子类(子接口)没有继承该静态方法,只能通过所在的接口名来调用
糖11:接口的私有方法
JDK9.0推出接口的私有方法
代码样例
public class Test {
public interface StaticAnimal{
private void move(){
System.out.println("I can move");
}
}
public interface StaticLandAnimal extends StaticAnimal{
//继承不到StaticAnimal的move方法
}
public static void main(String[] args) {
//错误引用
StaticAnimal.move();
StaticLandAnimal.move();
new StaticAnimal().move();
}
}
特性
- 解决多个默认方法/静态方法的内容重复问题
- 私有方法属于本接口,只能在本接口内使用,不属于子类/子接口
- 子类(子接口)没有继承该私有方法,也无法调用
- 静态私有方法可以被静态/默认方法调用,非静态私有方法被默认方法调用
糖12:try-with-resource
程序如果打开外部资源,那么使用后必须正确关闭
考虑异常因素,java提供try-catch-finally进行保证
JDK7.0提供try-with-resour,比try-catch-finally更加方便
代码样例
public class Test implements AutoCloseable {
private int age = 18;
@Override
public void close() throws Exception {
System.out.println("关闭成功");
}
public static void main(String[] args) {
try(Test11 OpenResource = new Test()){
System.out.println(OpenResource.age);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出样例
18
关闭成功
特性
- 资源对象必须实现AutoCloseable接口,即实现close方法
- 在try-catch块执行后会自动执行close方法
- JDK7要求定义临时变量接收
Test OpenResource = new Test();
try(Test TT = OpenResource)… - JDK9不在要求定义临时变量,可以直接使用
Test OpenResource = new Test();
try(OpenResource)…
糖13:ResourceBundle文件加载
JDK8及以前,ResourceBundle默认以ISO-8859-1方式加载文件
JDK9及以后,ResourceBundle默认以UTF-8方式加载文件
糖14:var类型
java以前一直是一种强类型的语言
每个变量在定义时候就确定了类型
JDK10推出了var:局部变量推断
代码样例
public class Test {
public static void main(String[] args) {
var a1 = 5;
var a2 = 0.025f;
var a3 = "abc";
int b1 = 5;
float b2 = 0.025f;
String b3 = "abc";
System.out.println(a1==b1);
System.out.println(a2==b2);
System.out.println(a3==b3);
}
}
输出样例
true
true
true
特性
- 避免了信息冗余
- 对齐了变量名
- 更容易阅读
- var可以用在局部变量上,非类成员变量
- var可以用在for/for-each循环中
- 声明时必须初始化
- 不能用在方法形参和返回类型
- 大面积滥用会导致代码整体阅读性变差
- var只在编译时起作用,没有在字节码中引入新的内容,也没有专门的JVM指令处理war
糖15:switch分支合并
JDK12推出
代码样例
public class Test {
public static void main(String[] args) {
String month = null;
int result;
switch (month){
case "Jan","Mar","July","Aug","Oct","Dec" -> result = 31;
case "Apr","June","Sep","Nov" -> result = 30;
case "Feb" -> result = 28;
default -> result = -1;
}
}
}
总结
到此本篇关于 Java 中语法糖的介绍和具体内容汇总以及 Java jdk 迭代的一些新特性的全部内容就介绍结束了,想要了解更多相关 Java 语法糖的详细内容以及 jdk 其他的新特性内容请搜索W3Cschool以前的文章或继续浏览下面的相关文章,希望大家以后多多支持我们!