1. 程式人生 > >java語法糖

java語法糖

虛擬 returns -h 計算機 源碼 true pre stat number

語法糖定義指的是,在計算機語言中添加某種語法,這種語法能使程序員更方便的使用語言開發程序,同時增強程序代碼的可讀性,避免出錯的機會;但是這種語法對語言的功能並沒有影響。
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語法糖