结合反编译工具了解Java中的语法糖

目录

  • 一、需要了解的概念
  • 二、使用到的反编译工具Xjad和Java Decompiler
  • 三、Java中的语法糖
    • 1、增强for循环(foreach)
    • 2、方法的可变参数
    • 3、import静态导入(static import)
    • 4、自动装箱(Autoboxing)与自动拆箱(Autounboxing)
    • 5、初始化代码块(构造代码块)
    • 6、枚举(ENUM)

一、需要了解的概念

  1. 语法糖(Syntactic sugar):也译为糖衣语法,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。(语法糖是编译器级别的新特性,也就是说让开发人员写更少、更简单的代码,完成相同的功能)(来源:百度百科)。
  2. 反编译:高级语言源程序经过编译变成可执行文件(在Java中就是由javac.exe工具将[.java文件–>.class文件]),反编译就是逆过程。
  3. 解语法糖:语法糖的存在主要是方便开发人员使用。但是,Java虚拟机并不支持这些语法糖,这些语法糖在编译阶段就会被还原成简单的基础语法结构(反编译就是将这些基本语法结构,再以高级语言的方式展现出来),这个过程就是解语法糖。

二、使用到的反编译工具Xjad和Java Decompiler

  1. Xjad 百度云下载链接 : Xjad点击下载
  • 提取码:hsyn
  1. Java DecDecompiler 百度云下载链接:Java DecDecompiler点击下载
  • 提取码:uruj

三、Java中的语法糖

1、增强for循环(foreach)

  1. 增强for循环foreach
    • 出现版本:JDK 5。
    • 作用:在迭代数组、集合方面,foreach为开发人员提供了极大的方便。
  2. 测试源代码如下
    public static void main(String[] args) 
    {
       int [] arrs = {1,2,3,4,5,6};
       for (int arr : arrs) {
       	System.out.println(arr);
       }
    }
    
  3. 使用反编译工具反编译生成的字节码
    结合反编译工具了解Java中的语法糖_第1张图片
  4. 结合源代码分析上图:我们可以看到字节码文件经过两款反编译工具反编译之后,foreach在底层依然是通过for循环+索引的方式来操作数组的,仅仅是在开发人员编写时有所便捷。
  5. 注意:虽然foreach用起来比for循环便捷,但是它是无法取代for循环的,在涉及到操作索引完成功能时依然得使用for循环,也就是说在功能性上(for循环语句>foreach语句)。

2、方法的可变参数

  1. 方法的可变参数
    • 出现版本:JDK 5
    • 作用:在调用方法时,该方法有不确定的参数个数时,可以使用可变参数。
  2. 测试源代码如下
    public static void main(String[] args) {
    	int sum = getSum(1,2,3,4,5);
    }
    private static int getSum(int... params) {
    	int sum = 0;
    	for (int param : params) {
    		sum += param;
    	}
    	return sum;
    }
    
  3. 使用反编译工具反编译生成的字节码
    结合反编译工具了解Java中的语法糖_第2张图片
  4. 结合源代码分析上图:其实在编译阶段底层在定义方法时的形式参数依然是数组,而且在调用方法时传递的实际参数也是数组。
  5. 使用注意事项
    • 方法的可变参数必须作为方法参数列表的最后一个参数;
    • 可变参数在方法参数列表中只能声明一个。

3、import静态导入(static import)

  1. import静态导入

    • 出现版本:JDK 5
    • 作用:可以使用impoet直接引用到另一个类中的方法,在该类中可以直接使用方法名调用另一个类中的功能。
  2. 测试源代码如下

    import static java.util.Arrays.sort;//使用了静态导入
    import java.util.Arrays;//未使用静态导入
    
    public class test {
    public static void main(String[] args) {
    	int [] arr = {1,21,3,7,12};
    	sort(arr);//使用静态导入:可以直接调用Arrays类中的sort方法
    	System.out.println(Arrays.toString(arr));//未使用静态导入:需要使用类名调用Arrays类中的toSting方法
    	}
    }
    
  3. 使用反编译工具反编译生成的字节码
    结合反编译工具了解Java中的语法糖_第3张图片

  4. 结合源代码分析上图:编译后静态导入语句不存在,且方法依然是使用类名.方法名的方式调用的。

  5. 使用注意事项

    • 在开发中不建议使用,因为容易混淆方法名,分不清调用的是哪一个类的静态方法;

4、自动装箱(Autoboxing)与自动拆箱(Autounboxing)

  1. 自动装箱与拆箱

    • 出现版本:JDK 5
    • 作用:可把一个基本类型变量直接赋值给对应的包装类型对象,也允许把包装类型的对象直接赋值给对应的基本数据类型变量,在JDK 5之前必须手动装箱与拆箱。
  2. 测试源代码如下

    	public static void main(String[] args) {
    		Integer num1 = 12;
    		int num2 = num1;
    	}
    
  3. 使用反编译工具反编译生成的字节码
    结合反编译工具了解Java中的语法糖_第4张图片

  4. 结合源代码分析上图:上面是反编译后的代码,可以看到程序底层依然是使用的手动装箱与拆箱,只不过是方便了开发人员的开发。

  5. 使用注意事项

    • 为什么要存在包装类型?
      • 包装类型既可以表示null也可以表示0(学生缺考与得0分的例子)。
      • Java的集合框架中只允许存储对象,不允许存储基本类型的值。
      • 包装类中封装了一些操作数据的方法,使开发过程变的便捷。
        结合反编译工具了解Java中的语法糖_第5张图片
    • Switch Case语法仅支持int类型的数据,它支持byte,short,char是因为自动类型转换为int类型,它也支持这几个基本类型的包装类型就是因为底层进行了手动拆箱操作。

5、初始化代码块(构造代码块)

  1. 初始化代码块

    • 出现版本:未知
    • 作用:初始化代码块中的代码在创建对象时被调用,在初始化代码块中编写的代码会出现在该类的构造器代码前面。
  2. 测试源代码如下

    public class Test {
    	{
    		System.out.println("初始化代码块");
    		int num=1;
    	}
    	public Test(){
    		System.out.println("构造器代码块");	
    	}
    	public static void main(String[] args) {
    		Test test = new Test();
    	}
    }
    
  3. 使用反编译工具反编译生成的字节码
    结合反编译工具了解Java中的语法糖_第6张图片

  4. 结合源代码分析上图:编译后根本不存在初始化代码块,其中的代码作为构造器中的前几行代码。

  5. 使用注意事项

    • 使用Xjad工具进行反编译,在初始化代码块中定义的局部变量的类型会改变,当我源代码中定义局部变量int i=1时,他会变成boolean类型,当定义int i=45;时他会变成byte类型的数值,如下图;
      结合反编译工具了解Java中的语法糖_第7张图片

6、枚举(ENUM)

  1. 枚举

    • 出现版本:JDK 5
    • 作用:枚举主要用于表示事物固定的几种类型。
  2. 测试源代码如下

    enum Season{
    	SPRING,SUMMER,AUTUMN,WINTER
    }
    
  3. 使用反编译工具反编译生成的字节码
    结合反编译工具了解Java中的语法糖_第8张图片

  4. 结合源代码分析上图:经过Xjad反编译后我们可以看到枚举是就是一种特殊的类,它继承自Enum类,其中的构造方法是私有的,只能在本类中创建有限个数的实例。

  5. 使用注意事项
    详细了解枚举

你可能感兴趣的:(Java学习记录)