Java中部分常见语法糖

语法糖(Syntactic Sugar),也称糖衣语法,指在计算机语言中添加的某种语法,这种语法对语言本身功能来说没有什么影响,只是为了方便程序员的开发,提高开发效率。说白了,语法糖就是对现有语法的一个封装。
参考:https://blog.csdn.net/danchu/article/details/54986442

泛型

java泛型学习笔记
http://blog.csdn.net/uncle_gy/article/details/77881849
java泛型擦除和泛型重载
http://blog.csdn.net/uncle_gy/article/details/78501893
java的PECS原则
http://blog.csdn.net/uncle_gy/article/details/77877002

自动装箱、拆箱和循环遍历(Foreach)

示例代码:

import java.util.List;
import java.util.ArrayList;

public class JavaCandy{
    public static void main(String[]args){
        List list=new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        int sum=0;
        for(int i:list){
            sum+=i;
        }
        System.out.println(sum);
    }
}

反编译class

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class JavaCandy
{
  public static void main(String[] paramArrayOfString)
  {
    ArrayList localArrayList = new ArrayList();
    localArrayList.add(Integer.valueOf(1));
    localArrayList.add(Integer.valueOf(2));
    localArrayList.add(Integer.valueOf(3));
    int i = 0;
    for (Iterator localIterator = localArrayList.iterator(); localIterator.hasNext();)
    {
      int j = ((Integer)localIterator.next()).intValue();
      i += j;
    }
    System.out.println(i);
  }
}

结果分析:

看到自动调用了以下语句:

 localArrayList.add(Integer.valueOf(1));//装箱
 int j = ((Integer)localIterator.next()).intValue();//拆箱

自动装箱拆箱的陷阱

实例代码:
public class JavaCandy{
    public static void main(String[]args){
        Integer a=1;
        Integer b=2;
        Integer c=3;
        Integer d=3;
        Integer e=321;
        Integer f=321;
        Long g=3L;
        System.out.println(c==d);
        System.out.println(e==f);
        System.out.println(c==(a+b));
        System.out.println(c.equals(a+b));
        System.out.println(g==(a+b));
        System.out.println(g.equals(a+b));
    }
}

反编译代码:

import java.io.PrintStream;

public class JavaCandy
{
  public static void main(String[] paramArrayOfString)
  {
    Integer localInteger1 = Integer.valueOf(1);
    Integer localInteger2 = Integer.valueOf(2);
    Integer localInteger3 = Integer.valueOf(3);
    Integer localInteger4 = Integer.valueOf(3);
    Integer localInteger5 = Integer.valueOf(321);
    Integer localInteger6 = Integer.valueOf(321);
    Long localLong = Long.valueOf(3L);
    System.out.println(localInteger3 == localInteger4);
    System.out.println(localInteger5 == localInteger6);
    System.out.println(localInteger3.intValue() == localInteger1.intValue() + localInteger2.intValue());
    System.out.println(localInteger3.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue())));
    System.out.println(localLong.longValue() == localInteger1.intValue() + localInteger2.intValue());
    System.out.println(localLong.equals(Integer.valueOf(localInteger1.intValue() + localInteger2.intValue())));
  }
}
输出结果

Java中部分常见语法糖_第1张图片

Integer.valueof()方法

public static Integer valueOf(int i) {
    return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}

可以看到如果在(-128,128]的区间内的值就会直接从SMALL_VALUES数组中直接取值,如果大于这个范围就会新建一个类。

什么是SMALL_VALUES[i+128]

private static final Integer[] SMALL_VALUES = new Integer[256];

自动拆箱和装箱操作是一个耗费资源的过程,所以比较小的值就直接保存到内存里。

变长参数

示例代码:
public class JavaCandy{
    public static void method(int...a){
        for(int i:a)
            System.out.println(i);
    }
    public static void main(String[]args){
        System.out.println("this is method(1);");
        method(1);
        System.out.println("this is method(1,2);");
        method(1,2);
        System.out.println("this is method(1,2,3);");
        method(1,2,3);
        System.out.println("this is method(1,2,3,4);");
        method(1,2,3,4);
    }
}
反编译结果
import java.io.PrintStream;

public class JavaCandy
{
  public static void method(int... paramVarArgs)
  {
    for (int k : paramVarArgs) {
      System.out.println(k);
    }
  }

  public static void main(String[] paramArrayOfString)
  {
    System.out.println("this is method(1);");
    method(new int[] { 1 });
    System.out.println("this is method(1,2);");
    method(new int[] { 1, 2 });
    System.out.println("this is method(1,2,3);");
    method(new int[] { 1, 2, 3 });
    System.out.println("this is method(1,2,3,4);");
    method(new int[] { 1, 2, 3, 4 });
  }
}

可以看到此时参数自动变为数组类型。

条件编译

示例代码:

public class JavaCandy{

    public static void main(String[]args){
        if(true){
            System.out.println("block1");
        }else{
            System.out.println("block2");
        }
    }
}

反编译结果:

import java.io.PrintStream;

public class JavaCandy
{
  public static void main(String[] paramArrayOfString)
  {
    System.out.println("block1");
  }
}

此时在if语句中会根据布尔值常量的真假,编译器会把分支中不成立的代码块消除掉。这一工作在编译器解除语法糖阶段完成。
只有if语句才有上面的效果,其他语句会显示拒绝编译。
比如:

public class JavaCandy{

    public static void main(String[]args){
        while(false){
            System.out.println("block1");
        }
    }
}

输出结果:
Java中部分常见语法糖_第2张图片

java中类的定义使用class,枚举类的定义使用enum。在Java的字节码结构中,其实并没有枚举类型,枚举类型只是一个语法糖,在编译完成后被编译成一个普通的类。这个类继承java.lang.Enum,并被final关键字修饰。

枚举类型

枚举类型就是一些具有相同特性的类常量

java中类的定义使用class,枚举类的定义使用enum。在Java的字节码结构中,其实并没有枚举类型,枚举类型只是一个语法糖,在编译完成后被编译成一个普通的类。这个类继承java.lang.Enum,并被final关键字修饰。

public enum Fruit {
    APPLE,ORINGE
}

使用jad对编译后的class文件进行反编译后得到:


public final class Fruit extends Enum
{

    public static Fruit[] values()
    {
        return (Fruit[])$VALUES.clone();
    }

    public static Fruit valueOf(String s)
    {
        return (Fruit)Enum.valueOf(Fruit, s);
    }

    private Fruit(String s, int i)
    {
        super(s, i);
    }
    //枚举类型常量
    public static final Fruit APPLE;
    public static final Fruit ORANGE;
    private static final Fruit $VALUES[];//使用数组进行维护

    static
    {
        APPLE = new Fruit("APPLE", 0);
        ORANGE = new Fruit("ORANGE", 1);
        $VALUES = (new Fruit[] {
            APPLE, ORANGE
        });
    }
}

你可能感兴趣的:(Java,Java基础)