zoukankan      html  css  js  c++  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.length;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好很多。

     有兴趣的可以自行了解:https://www.cnblogs.com/java-spring/p/9264406.html

    (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("");
        }
    }

    运行结果:

    (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核心技术》高阶,这里只是做一个学习记录,非原创,感兴趣的读者还请自行观看陈良育老师的课程。

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

  • 相关阅读:
    开发中常用的JS知识点集锦
    浏览器音频兼容和ffmpeg的音频转码使用
    web页面和小程序页面实现瀑布流效果
    微信小程序之支付密码输入demo
    Mac安装nginx配置过程
    前端工具mock的使用
    汇编语言学习
    Swift学习笔记
    如何快速融入团队并成为团队核心(四)
    如何快速融入团队并成为团队核心(三)
  • 原文地址:https://www.cnblogs.com/hzauxx/p/11699328.html
Copyright © 2011-2022 走看看