语法糖(Syntactic Sugar),也称糖衣语法,指在计算机语言中添加的某种语法,这种语法对语言本身功能来说没有什么影响,只是为了方便程序员的开发,提高开发效率。说白了,语法糖就是对现有语法的一个封装。
泛型
java泛型学习笔记
java泛型擦除和泛型重载
java的PECS原则
自动装箱、拆箱和循环遍历(Foreach)
示例代码:
import java.util.List;
import java.util.ArrayList;
public class JavaCandy{
public static void main(String[]args){
List<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
int sum=0;
for(int i:list){
sum+=i;
}
System.out.println(sum);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
反编译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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
结果分析:
看到自动调用了以下语句:
localArrayList.add(Integer.valueOf(1));//装箱
int j = ((Integer)localIterator.next()).intValue();//拆箱
1
2
自动装箱拆箱的陷阱
实例代码:
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));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
反编译代码:
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())));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
输出结果
Integer.valueof()方法
public static Integer valueOf(int i) {
return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}
1
2
3
可以看到如果在(-128,128]的区间内的值就会直接从SMALL_VALUES数组中直接取值,如果大于这个范围就会新建一个类。
什么是SMALL_VALUES[i+128]
private static final Integer[] SMALL_VALUES = new Integer[256];
1
自动拆箱和装箱操作是一个耗费资源的过程,所以比较小的值就直接保存到内存里。
变长参数
示例代码:
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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
反编译结果
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 });
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
可以看到此时参数自动变为数组类型。
条件编译
示例代码:
public class JavaCandy{
public static void main(String[]args){
if(true){
System.out.println("block1");
}else{
System.out.println("block2");
}
}
}
1
2
3
4
5
6
7
8
9
10
反编译结果:
import java.io.PrintStream;
public class JavaCandy
{
public static void main(String[] paramArrayOfString)
{
System.out.println("block1");
}
}
1
2
3
4
5
6
7
8
9
10
此时在if语句中会根据布尔值常量的真假,编译器会把分支中不成立的代码块消除掉。这一工作在编译器解除语法糖阶段完成。
只有if语句才有上面的效果,其他语句会显示拒绝编译。
比如:
public class JavaCandy{
public static void main(String[]args){
while(false){
System.out.println("block1");
}
}
}
1
2
3
4
5
6
7
8
输出结果:
java中类的定义使用class,枚举类的定义使用enum。在Java的字节码结构中,其实并没有枚举类型,枚举类型只是一个语法糖,在编译完成后被编译成一个普通的类。这个类继承java.lang.Enum,并被final关键字修饰。
枚举类型
枚举类型就是一些具有相同特性的类常量
java中类的定义使用class,枚举类的定义使用enum。在Java的字节码结构中,其实并没有枚举类型,枚举类型只是一个语法糖,在编译完成后被编译成一个普通的类。这个类继承java.lang.Enum,并被final关键字修饰。
public enum Fruit {
APPLE,ORINGE
}
1
2
3
使用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
});
}
}
---------------------
作者:uncle_gy