1. 程式人生 > >Java中部分常見語法糖

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<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
來源:CSDN
原文:https://blog.csdn.net/uncle_gy/article/details/78505498
版權宣告:本文為博主原創文章,轉載請附上博文連結!