语法糖java_Java语法糖

Java语法糖

语法糖:Syntactic sugar / Syntax sugar。

维基定义:语法糖是编程语言中的一种语法吗,用来使得程序语言更容易阅读或者更容易表达事务的处理过程。

-语法糖使得程序员更容易编写程序,更清晰准确表达业务逻辑。

-语法糖不仅仅是语法的转换,也包括一些小的改进。

-以下主要包括JDK5~12版本之间的重要的语法糖。

·JDK2(1.1~1.4)是普及版

·JDK5/6/7/8/11是长期稳定版

·JDK9/10/12是短期版本

下面列举一些语法糖:

一、for-each 和 枚举

(1)、for/for-each

int[] n=new int[5];

for(int i=0;i

n[i]=i;

}

for(int a:n){

System.out.println(a);

}

for VS for-each

for-each从JDK5.0开始引入

for-each语法更简洁

for-each避免越界错误

for 可以删除元素,for-each不可以删除/替换元素

for-each遍历时,不知道当前元素的具体位置索引

for-each只能正向遍历,不能反向遍历

for-each不能同时遍历2个集合

for和for-each性能接近

注:这里 for 和 for-each 性能接近并不是绝对的,遍历不同的数据结构会有不同的表现,总的来说,遍历数组结构两者性能相近,遍历链表结构时for-each性能会比for好很多。

(2)枚举类型

·枚举变量:变量的取值只在一个有限的集合内(如性别、星期几、颜色等)。

·Java5推出enum类型

-enum关键字声明枚举类,且都是Enum的子类(但不需也不许写 extends)

-enum内部有多少个值,就有多少个实例对象,有且仅有一个。

-不能直接 new 枚举类对象。

·Java的enum类型

-除了枚举的内容,还可以添加属性/构造函数/方法

-构造函数只能是package-private(default)或者private,内部调用。

-所有的enum类型都是Enum的子类,也继承了相应的方法。

-ordinal()返回枚举值所在的索引位置,从0开始。

-compareTo()比较两个枚举值的索引位置大小

-toString()返回枚举值的字符串表示

-valueOf()将字符串初始化为枚举对象

-values()返回所有的枚举值

enum Day{

Monday,Tuesday,Wednesday,Thursday,FridaySaturday,Sunday;

}

总结:

for-each循环(5):避免数组越界,提倡使用。

枚举(5):限定取值集合,减少实例对象,提倡使用。

二、不定项参数和静态导入

(1)不定项参数(可变参数)

· 普通函数的形参列表是固定个数/类型/顺修

·JDK 5 提供了不定项参数(可变参数)功能

-类型后面加三个点,如 int.../double.../String...

-可变参数,本质上就是一个数组。

·一个方法只能有一个一个不定项参数,且必须位于参数列表的最后。

·重载的优先级规则1:固定参数的方法,比可变参数优先级更高。

·重载的优先级规则2:调用语句,同时与两个带可变参数的方法匹配,则报错。

示例代码:

public class Main {

public static void main(String[] args){

print();

print("a");

print("a","a");

print("a","a","a");

}

public static void print(String... args){

System.out.println(args.length);

for(String arg:args){

System.out.print(arg+" ");

}

System.out.println("");

}

}

运行结果:

fa5cc15ae56fcb13cbac17314adf9df3.png

(2)静态导入

·import 导入程序所需要的类

·import static 导入一个类的静态方法和静态变量(JDK5引入)

-少使用 * 通配符,不滥用,最好具体到静态变量或方法。

-静态方法名具有明确特征,如有重名,需要补充类名。

示例:

import static java.lang.System.out;

out.println("Hello World");

这个还比较常用,能让代码更加简洁。

总结:

不定项参数(5):注意方法重载的优先级,建议少用。

静态导入(5):有大量静态方法调用时使用,注意 “ * ” 不滥用。

三、自动拆箱和装箱、多异常并列、数值类型赋值优化

(1)、自动装箱和拆箱

自动装箱和拆箱(auto-boxing/auto-unboxing)

-从JDK5.0开始引入,简化基本类型和对象转换的写法

-基本类型:boolean、byte、char、int、short、long、float、double

-对象:Boolean、Byte、Character、Integer、Short、Long、Float、Double

装箱:基本类型的值被封装为一个包装类对象。

拆箱:一个包装类对象被拆开并获取对应的值。

示例:

Integer obj1=5; //自动装箱

Integer obj2=Integer.valueOf(5);

int a1=obj1; //自动拆箱

int a2=obj1.intValue();

自动装箱和拆箱的注意事项:

-装箱和拆箱时编译器的工作,在 class 中已经添加转化。虚拟机没有自动装箱和拆箱的语句。

-==:基本类型时内容相等,对象时指针是否相同(内存同一个区域)

-基本类型没有空值,对象有null,可能触发NullPointerException。

-当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基本数据类型进行运算。

-谨慎使用多个非同类的数值类对象进行运算。

(2)、多异常并列

多个异常并列在一个catch中

-从JDK7.0开始引入,简化写法

示例:

try{

}catch(IOException | SQLException ex){

//一个catch写多个异常,异常之间用管道符连接

//异常处理

}

-多个异常之间不能有(直接/间接)继承关系,如果有,则报错。

-且不同异常的异常处理方式统一才可以使用多异常并列。

(3)、数值类型赋值优化

Java 7 的新语法:整数类型用二进制数赋值

-避免二进制计算

-byte、short、int、long

Java 7 的新语法:在数值字面量(literal)中使用下划线。

-增加数字的可读性和纠错功能

-short、int、long、float、double

-下划线只能出现数字中间,前后必须有数字

-允许在二/八/十/十六进制的数字中使用。

整数类型可以用二进制数直接赋值。

示例:

byte a1=(byte) 0b00100001;

short a2=(short) ob1010000101000101;

int a3=0b101;

int a4=0B101; //B可以大小写

总结:

自动拆箱和装箱(5):避免多个不同类型对象共同运算。

多异常并列(7):不建议使用,针对每一异常单独处理。

数值类型赋值优化(7):优化显示,避免错误,建议使用。

四、接口方法

接口的默认方法:

Java最初的设计中,接口的方法都是没有实现的,公开的。

Java 8 推出接口的默认方法/静态方法(都带实现的),为Lambda表达式提供支持。

-以 default 关键字标注,其他的定义和普通函数一样。

-规则1:默认方法不能重写Object中的方法。

-规则2:实现类可以继承/重写父接口的默认方法

-规则3:接口可以继承/重写父接口的默认方法

-规则4:当父类和父接口都有(同名同参数)的默认方法,子类继承父类的默认方法,这样就可以兼容JDK7及以前的代码。

-规则5:子类实现了2个接口(均有同名同参数的默认方法),那么编译失败,必须在子类中重写这个default方法。

简单示例:

public interface Animal {

public default void move(){

System.out.println("I can move.");

}

}

接口的静态方法:

Java 8 接口的静态方法(带实现的)

-该静态方法属于本接口,不属于子类/子接口。

-子类(子接口)没有继承该静态方法,只能通过所在接口名来调用。

简单示例:

public interface Animal {

public static void move(){

System.out.println("I can move.");

}

}

接口的私有方法:

Java 9 接口的私有方法(带实现的)

-解决多个默认方法/静态方法的内容重复问题。

-私有方法属于本接口,只能本接口内使用,不属于子类/子接口。

-子类(子接口)没有继承该私有方法,也无法调用。

-静态私有方法可以被静态/默认方法调用,非静态私有方法被默认方法调用。

接口 VS 抽象类

相同点(截止到 Java 12以前,接口和抽象类对比)

-都是抽象的,都不能被实例化,即不能被new。

-都可以有实现方法

-都可以不需要继承者实现所有的方法。

不同点(截至到 Java 12以前,接口和抽象类对比)

-抽象类最多继承一个,接口可以实现多个

-接口的变量默认时 public static final ,且必须有初值,子类不能修改,而抽象类的变量默认时 default,子类可以继承修改。

-接口没有构造函数,抽象类有构造函数。

-接口没有main函数,抽象类可以有main函数.

-接口有 public / default / private 的方法,抽象类有 public / private / protected / 不写关键字的(defaule) 的方法。

总结:

接口的方法(8/9):建议少用,如有 Lambda 表达式需求,可使用

-默认方法:default标注,可以为子类/子接口所继承/改写。

-静态方法:static 标注,只属于本接口,不属于子类/子接口,子类/子接口可访问。

-私有方法:private标注,只属于本接口,不属于子类/子接口。

五、try-with-resource和Resource Bundle文件加载优化

(1)、try-with-resource

程序如果打开外部资源,那么在使用后需要保证正确关闭。

考虑异常因素,Java提供 try-catch-finally进行保证。

JDK 7 提供 try-with-resource ,比 try-catch-finally更简便。

JDK 7 提供 try-with-resource

-资源要求定义在 try 中,若已经在外部定义,则需要一个本地变量。

JDK 9 不再要求定义临时变量,可以直接使用外部资源变量。

try-with-resource原理

-资源对象必须实现 AutoCloseable接口,即实现 close 方法。

简单示例:

try(FileInputStream f=...){

}catch (Exception e){

}

(2)、ResourceBundle文件加载

Java 8 及以前,ResourceBundle默认以 ISO-8859-1方式加载 Properties文件。

-需要利用 native2ascii工具(JDK自带)对文件进行转义。

JDK 9 及以后,ResourceBundle默认以UTF-8方式加载 Properties文件。

-JDK9及以后已经删除natice2ascii工具。

-新的 Properties文件可以直接以UTF-8保存。

-已利用native2ascii工具转化后的文件,不受影响。即ResourceBundle若解析文件不是有效的UTF-8,则以ISO-8859-1方式加载。

总结:

try-with-resource(7/9):资源自动关闭,避免错误,建议使用。

ResourceBundle文件加载优化(9):默认以UTF-8加载。

六、var类型和 switch

(1)var类型

Java 以前一直时一种强类型的程序语言

-每个变量在定义时就确定了类型

-类型固定了,就不能更改

Java 10 推出var:局部变量推断。

-避免了信息冗余

-对齐了变量名

-更容易阅读

-本质上还是强类型语言,编译器负责推断类型,并写入字节码文件。因此推断后不能更改。

var的限制

-可以用在局部变量上,非类成员变量。

-可以用在for/for-each循环中

-声明时必须初始化

-不能用在方法(形式)参数和返回类型

-大面积滥用会使代码整体阅读性变差。

-var只在编译时起作用,没有在字节码中引入新的内容也没有专门的JVM指令处理 var。

(2)、switch

switch,多分支选择语句

-支持的类型:byte/Byte,short/Short,int/Integer,char/Character,String(7.0),Enm枚举(5.0),不支持long/float/double。

-多分支合并,采用 -> 直接连接到判定条件和动作(JDK12支持)

-switch直接在表达式赋值(JDK12支持)

简单示例:

switch(month){

case "Jan","Mar","May","July","Aug","Oct","Dec" -> result=31;

case "Apr","June","Sep","Nov" -> result=30;

default -> result=-1;

}

总结:

var类型(10):类型自动推断,不滥用,建议在局部情况下使用,如for循环。

switch(5/7/12):多分支判断,注意在不同版本下支持的语法不同。

综述:

语法糖:了解新特性,知晓其优缺点,特别是适用的版本,谨慎使用。

本篇博客主要内容皆为中国大学mooc上,陈良育老师的《Java核心技术》高阶,这里只是做一个学习记录,非原创,感兴趣的读者还请自行观看陈良育老师的课程。

吾生也有涯,而知也无涯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值