java語法糖
語法糖定義指的是,在計算機語言中添加某種語法,這種語法能使程序員更方便的使用語言開發程序,同時增強程序代碼的可讀性,避免出錯的機會;但是這種語法對語言的功能並沒有影響。
Java中的泛型,變長參數,自動拆箱/裝箱,條件編譯等都是
泛型定義java的泛型只在源代碼存在,只供編輯器檢查使用,編譯後的字節碼文件已擦除了泛型類型(類型T不確定)
public static void main(String[] args) {
List<String> stringList = new ArrayList<String>();
stringList.add("oliver");
System.out.println(stringList.get(0));
}
將上面的代碼的字節碼反編譯後:
public static void main(String args[])
{
List stringList = new ArrayList();
stringList.add("oliver");
System.out.println((String)stringList.get(0));
}
自動拆箱/裝箱
裝箱過程:把基本類型用它們對應的包裝類型進行包裝,使基本類型具有對象特征。拆箱過程:與裝箱過程相反,把包裝類型轉換成基本類型。 基本數據類型與對象的差別
基本數據類型不是對象,也就是使用int、double、boolean等定義的變量、常量。
基本數據類型沒有可調用的方法。
eg: int t = 1; t. 後面是沒有方法滴。
Integer t =1; t. 後面就有很多方法可讓你調用了。
什麽時候自動裝箱例如:Integer i = 100;
相當於編譯器自動為您作以下的語法編譯:Integer i = Integer.valueOf(100);
public static void main(String[] args){ Integer i = Integer.valueOf(100); // 弄成了對象 * Parameters: i是an int value Returns: an Integer instance representing i.*/
Integer ii = new Integer(100);
System.out.println(i==ii); //false
System.out.println(i.equals(ii)); //內容肯定是true的
Integer aa =100; Integer bb =100;
System.out.println(aa==bb);//true 從緩沖池中取得的東西
System.out.println(i==aa); //true 從同一個緩存池中取得的對象
}
什麽時候自動拆箱
自動拆箱(unboxing),也就是將對象中的基本數據從對象中自動取出。如下可實現自動拆箱:
1 Integer i = 10; //裝箱2 int t = i; //拆箱,實際上執行了 int t = i.intValue();
在進行運算時,也可以進行拆箱。
1 Integer i = 10;2 System.out.println(i++); 備註:包裹類型的“==”運算在沒有遇到算數運算符的情況下不會自動拆箱
Integer的自動裝箱
說明:
equals() 比較的是兩個對象的值(內容)是否相同。(這裏的方法已經是重寫過的)
"==" 比較的是兩個對象的引用(內存地址)是否相同,也用來比較兩個基本數據類型的變量值是否相等。比較的是是不是同一個對象
源碼絕對重要
前面說過,int 的自動裝箱,是系統執行了 Integer.valueOf(int i),先看看Integer.java的源碼:
public
static
Integer valueOf(
int
i) {
if
(i >= -
128
&& i <= IntegerCache.high)
// 沒有設置的話,IngegerCache.high 默認是127
return
IntegerCache.cache[i +
128
];
else
return
new
Integer(i);
}
對於–128到127(默認是127)之間的值,Integer.valueOf(int i) 返回的是緩存的Integer對象(並不是新建對象)
而其他值,執行Integer.valueOf(int i) 返回的是一個新建的 Integer對象,所以範例中,i1與i2 指向的是不同的對象。
public static void main(String[] args){
Integer i = Integer.valueOf(1000); // 弄成了對象
Integer ii =1000;
System.out.println(i==ii); //false
Integer iii =10; //自動裝箱
System.out.println(iii == (Integer.valueOf(10)));//true
}
//不使用自動拆裝箱和其他的對象的用法是一樣的
1 Integer i3 =new Integer(100);2 Integer i4 =new Integer(100);
3 System.out.println("i3==i4: "+(i3==i4));//顯示false 循環歷遍(foreach)
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for(Integer num : list){
System.out.println(num);
}
}
再探拆箱裝箱:
public static void main(String[] args){
Integer i = 100;
//System.out.println(i.intValue());//100,將對象拆箱成基本數據類型
Integer i1 = 2255;
Integer i2 = 2255;
System.out.println(i1==i2); //false 不是從緩沖池裏面拿的
System.out.println(i1.equals(i2));//內容肯定是相同的
Integer g1 =10;
Integer g2 =10;
System.out.println(g1==g2); //true
System.out.println(g1.equals(g2));//true
//Interger只在某個特定範圍才是從緩存拿來的
//而String類型的不論什麽,都是緩存的
Boolean b1 = false;
Boolean b2 = false;
System.out.println(b1==b2); //true
System.out.println(b1.equals(b2));//true
String s1= "abc";
String s2 ="abc";
System.out.println(s1==s1); //true
System.out.println(s1.equals(s2));//true
System.out.println("is equals?"+new String("abc").equals(new String("abc")));//true
System.out.println("is equals?"+new String("abc")==(new String("abc"))); //false
/**
* 針對String作為一個基本類型來使用:
1。如果String作為一個基本類型來使用,那麽我們視此String對象是String緩沖池所擁有的。
2。如果String作為一個基本類型來使用,並且此時String緩沖池內不存在與其指定值相同的String對象,那麽此時虛擬機將為此創建新的String對象,並存放在String緩沖池內。
3。如果String作為一個基本類型來使用,並且此時String緩沖池內存在與其指定值相同的String對象,那麽此時虛擬機將不為此創建新的String對象,而直接返回已存在的String對象的引用。
*/
}
Java 可變長參數
public static void main(String[] args) {
System.out.println(add(2, 3)); // 5
System.out.println(add(2, 3, 5));// 10
}
static int add(int x, int ...args) {
int sum = x;
for (int i = 0; i < args.length; i++) {
sum += args[i];
}
return sum;
}
public static void main(String[] args) {
print();
print("hello");
print("hello","lisi");
print("hello","張三", "alexia");
/**
* hello
hello lisi
hello 張三 alexia
*/
System.out.println("加"+add()); // 0.0
System.out.println("加"+add(1.0+2.3)); //3.3
System.out.println("加"+add(1.0+2.2+0.1));//3.3
}
//用戶傳入若幹個double型數字,然後進行相加
static double add(double ...args){
double sum= 0 ;
for(double i :args)
sum+=i;
return sum;
}
//在具有可變長參數的方法中可以把參數當成數組使用,例如可以循環輸出所有的參數值。
static void print(String... args){
String str = "";
for(String temp:args)
str = str+" "+temp;
// System.out.println(temp);
System.out.println(str);
}
//適用於參數個數不確定,類型確定的情況
可變參數的特點:
(1)、只能出現在參數列表的最後;
(2)、...位於變量類型和變量名之間,前後有無空格都可以;
(3)、調用可變參數的方法時,編譯器為該可變參數隱含創建一個數組,在方法體中一數組的形式訪問可變參數。
}
枚舉類型:見下一篇
java語法糖