什么是语法糖?

语法糖
    其实就是指 java 编译器把 *.java 源码编译为 \*.class 字节码的过程中,**自动生成**和**转换**的一些代码,主要是为了减轻程序员的负担,算是 java 编译器给我们的一个额外福利。

默认构造函数
    java编译器帮我们加上的无参构造器,调用父类 Object 的无参构造方法
自动拆装箱 
    基本类型和其包装类型的相互转换过程,称为拆装箱
    在JDK 5以后,它们的转换可以在编译期自动完成
    Integer x = 1; =>//基本类型赋值给包装类型,称为装箱 Integer x = Integer.valueOf(1);
    int y = x;     =>//包装类型赋值给基本类型,称谓拆箱 int y = x.intValue();
泛型集合取值

    泛型也是在 JDK 5 开始加入的特性,但 java 在**编译泛型代码后**会执行 **泛型擦除** 的动作,即泛型信息在编译为字节码之后就**丢失**了,实际的类型都当做了 **Object** 类型来处理:
    所以调用get函数取值时,有一个类型转换的操作
    Integer x = (Integer) list.get(0);
    如果要将返回结果赋值给一个int类型的变量,则还有**自动拆箱**的操作
    int x = (Integer) list.get(0).intValue();Copy
可变参数
    可变参数 **String…** args 其实是一个 **String[]** args 
    如果未传递参数,等价代码为方法名(new String[]{}),**创建了一个空数组**,而不是直接传递的null
foreach
数组使用foreach编译器转换为fori循环
如果是集合使用foreach
集合要使用foreach,需要该集合类实现了Iterable接口,因为集合的遍历需要用到迭代器Iterator

switch字符串

   

public class Demo6 {
   public static void main(String[] args) {
      String str = "hello";
      switch (str) {
         case "hello" :
            System.out.println("h");
            break;
         case "world" :
            System.out.println("w");
            break;
         default:
            break;
      }
   }
}


在编译器中执行的操作   

public class Demo6 {
   public Demo6() {
      
   }
   public static void main(String[] args) {
      String str = "hello";
      int x = -1;
      //通过字符串的hashCode+value来判断是否匹配
      switch (str.hashCode()) {
         //hello的hashCode
         case 99162322 :
            //再次比较,因为字符串的hashCode有可能相等
            if(str.equals("hello")) {
               x = 0;
            }
            break;
         //world的hashCode
         case 11331880 :
            if(str.equals("world")) {
               x = 1;
            }
            break;
         default:
            break;
      }

      //用第二个switch在进行输出判断
      switch (x) {
         case 0:
            System.out.println("h");
            break;
         case 1:
            System.out.println("w");
            break;
         default:
            break;
      }
   }
}

过程说明:

- 在编译期间,单个的switch被分为了两个
  - 第一个用来匹配字符串,并给x赋值
    - 字符串的匹配用到了字符串的hashCode,还用到了equals方法
    - 使用hashCode是为了提高比较效率,使用equals是防止有hashCode冲突(如BM和C.)
  - 第二个用来根据x的值来决定输出语句
switch枚举
 

public class Demo7 {
   public static void main(String[] args) {
      SEX sex = SEX.MALE;
      switch (sex) {
         case MALE:
            System.out.println("man");
            break;
         case FEMALE:
            System.out.println("woman");
            break;
         default:
            break;
      }
   }
}

enum SEX {
   MALE, FEMALE;
}


 

编译器中执行的代码如下

public class Demo7 {
   /**     
    * 定义一个合成类(仅 jvm 使用,对我们不可见)     
    * 用来映射枚举的 ordinal 与数组元素的关系     
    * 枚举的 ordinal 表示枚举对象的序号,从 0 开始     
    * 即 MALE 的 ordinal()=0,FEMALE 的 ordinal()=1     
    */ 
   static class $MAP {
      //数组大小即为枚举元素个数,里面存放了case用于比较的数字
      static int[] map = new int[2];
      static {
         //ordinal即枚举元素对应所在的位置,MALE为0,FEMALE为1
         map[SEX.MALE.ordinal()] = 1;
         map[SEX.FEMALE.ordinal()] = 2;
      }
   }

   public static void main(String[] args) {
      SEX sex = SEX.MALE;
      //将对应位置枚举元素的值赋给x,用于case操作
      int x = $MAP.map[sex.ordinal()];
      switch (x) {
         case 1:
            System.out.println("man");
            break;
         case 2:
            System.out.println("woman");
            break;
         default:
            break;
      }
   }
}

枚举类

enum SEX {
   MALE, FEMALE;
}


 

转换后的代码

public final class Sex extends Enum<Sex> {   
   //对应枚举类中的元素
   public static final Sex MALE;    
   public static final Sex FEMALE;    
   private static final Sex[] $VALUES;
   
    static {       
        //调用构造函数,传入枚举元素的值及ordinal
        MALE = new Sex("MALE", 0);    
        FEMALE = new Sex("FEMALE", 1);   
        $VALUES = new Sex[]{MALE, FEMALE}; 
   }
     
   //调用父类中的方法
    private Sex(String name, int ordinal) {     
        super(name, ordinal);    
    }
   
    public static Sex[] values() {  
        return $VALUES.clone();  
    }
    public static Sex valueOf(String name) { 
        return Enum.valueOf(Sex.class, name);  
    } 
   
}

匿名内部类

public class Demo8 {
   public static void main(String[] args) {
      Runnable runnable = new Runnable() {
         @Override
         public void run() {
            System.out.println("running...");
         }
      };
   }
}

转换后的代码

public class Demo8 {
   public static void main(String[] args) {
      //用额外创建的类来创建匿名内部类对象
      Runnable runnable = new Demo8$1();
   }
}

//创建了一个额外的类,实现了Runnable接口
final class Demo8$1 implements Runnable {
   public Demo8$1() {}

   @Override
   public void run() {
      System.out.println("running...");
   }
}

如果匿名内部类中引用了局部变量

public class Demo8 {
   public static void main(String[] args) {
      int x = 1;
      Runnable runnable = new Runnable() {
         @Override
         public void run() {
            System.out.println(x);
         }
      };
   }
}


 

转化后代码

public class Demo8 {
   public static void main(String[] args) {
      int x = 1;
      Runnable runnable = new Runnable() {
         @Override
         public void run() {
            System.out.println(x);
         }
      };
   }
}

final class Demo8$1 implements Runnable {
   //多创建了一个变量
   int val$x;
   //变为了有参构造器
   public Demo8$1(int x) {
      this.val$x = x;
   }

   @Override
   public void run() {
      System.out.println(val$x);
   }
}


 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿咕咚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值