天天看点

[java]语法糖?甜么?

文章目录

    • 1. 什么是语法糖
    • 2. Java中的语法糖
      • 1)switch支持String
      • 2)范型
      • 3) 自动拆箱、装箱
      • 4)foreach

1. 什么是语法糖

语法糖是指为了方便程序员使用的一种语法结构,在编译期间会被转换为基础的语法结构。其实我们每天都在和语法糖打交道,只是我们自己不了解。下面我们看看在Java中都有哪些语法糖。

2. Java中的语法糖

1)switch支持String

在switch中比较的是String的hashcode。

class SwitchDemo {
    public static void main(String[] args) {
       String s = "hello";
       String s1 = "nsn";

       switch (s) {
           case "hello":
               System.out.println("hello");
               break;
           case "nsn":
               System.out.println("nsn");
               break;
       }
    }
}

// 编译后
class SwitchDemo {
        SwitchDemo() {
        }

        public static void main(String[] args) {
            String s = "hello";
            String s1 = "nsn";
            byte var4 = -1;
            switch(s.hashCode()) {
            case 109385:
                if (s.equals("nsn")) {
                    var4 = 1;
                }
                break;
            case 99162322:
                if (s.equals("hello")) {
                    var4 = 0;
                }
            }

            switch(var4) {
            case 0:
                System.out.println("hello");
                break;
            case 1:
                System.out.println("nsn");
            }
        }
    }
           

2)范型

通常情况下,处理泛型有两种方式:

1.Code specialization。在实例化一个泛型类或泛型方法时都产生一份新的目标代码。 C++就是使用这种方式。C++编译器会为每一个泛型类实例生成一份执行代码。执行代码中integer list和string list是两种不同的类型。

2.Code sharing。对每个泛型类只生成唯一的一份目标代码;Java就是使用这种方式。将多种泛型类形实例映射到唯一的字节码表示是通过类型擦除实现的,在编译期就会擦除类型。

class ParadigmDemo {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
    }
}

// 编译后
class ParadigmDemo {
        ParadigmDemo() {
        }

        public static void main(String[] args) {
          	// 可以看到后面ArrayList的类型已经去掉,但是引用的类型还在。不知道为什么,望大神指点
            List<Integer> list = new ArrayList();
            list.add(1);
            list.add(2);
        }
    }
           

所以方法重载是不能用带范型的参数进行区分的,因为编译过后,他们的函数签名是相同的,编译器会报错,如下图。

[java]语法糖?甜么?

3) 自动拆箱、装箱

自动拆箱装箱是使用XXX.valueOf()和xxxValue()方法

class BoxDemo {
    public static void main(String[] args) {
        int a = 10;
        Integer b = a;

        Integer c = 1000;
        int d = c;
    }
}

// 编译后
class BoxDemo {
  BoxDemo() {
  }

  public static void main(String[] args) {
    int a = 10;
    Integer b = Integer.valueOf(a);
    Integer c = 1000;
    // 按理说c赋值给d应该调用intValue方法拆箱,但是并没有。望大神指点。
    int d = c;
  }
}
           

4)foreach

可以看到,foreach是使用迭代器实现的。

class ForDemo {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        for (int i : list){
            System.out.println(i);
        }
    }
}

// 编译后
class ForDemo {
  ForDemo() {
  }

  public static void main(String[] args) {
    List<Integer> list = new ArrayList();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    Iterator var2 = list.iterator();

    while(var2.hasNext()) {
      int i = (Integer)var2.next();
      System.out.println(i);
    }
  }
}
           

其实语法糖有很多,文中只是列举了常见的几种,其他的大家可以通过class文件去自行了解。语法糖就是提供给开发人员便于开发的一种语法而已,可以提高我们的开发效率。