Java入門第5節——類型轉換和算術運算符

系列連載文章,大家可以從我的專欄學習Java入門基礎知識,後續也會有更高級的Java特性、企業級開發框架,也有平常工作中的技術總結和分享,歡迎關注我的CDSN博客。同時可關注微信公衆號“Java開發之旅”,獲得更多技術資料! 

目錄

閒言碎語

數據類型轉換

算術運算符

有趣的++、--

“特殊”的算術運算符

“+”在字符串中的應用

算術運算符的優先級

小結


閒言碎語

在上一節中,我們認識了Java中的基本數據類型(四類八種),並且定義了這些類型的變量,那麼在這一節當中,我們對數據類型和變量進行更深一步的學習。

 

數據類型轉換

上節課當中,當我們聲明變量時,敢於嘗試的朋友會發現以下代碼也可以正常運行:

public class Hello {
​
    public static void main(String[] args) {
        //左邊聲明的是double雙精度浮點,右邊賦的值卻是整數
        double test = 1;
        //打印是沒問題的
        System.out.println(test);
    }
}

what???double類型不是雙精度浮點的小數嗎?怎麼會可以存儲整數呢?

是的你沒有看錯,確實是可以的,只不過會自動升級爲小數,這就是Java當中的數據類型轉換在發揮作用。

在Java當中,有些數據類型之間是可以互相兼容、互相轉換的,這個機制叫做數據類型轉換,就是將等號右邊的數據類型轉換爲左邊的數據類型。

一般的,大的類型可以向下兼容小的類型,此時等號右邊的小類型會自動提升爲左邊的大類型,叫做自動轉換。拿所有的數值類型來說(boolean不存在自動轉換和強轉,char稍後結合String講解),在不超過各自的取值範圍的情況下,自動轉換關係如下圖所示:

上圖中的每一個數據類型,都可以兼容它右邊的所有數據類型,也就是說double可以兼容所有的數據類型,float可以兼容long、int、short、byte,以此類推。

所以以下代碼都是合法的(注意看註釋):

public class Hello {
​
    public static void main(String[] args) {
        //聲明一個byte類型變量
        byte a = 1;
        //將byte類型賦值給short類型,合法
        short b = a;
        //將short類型賦值給int類型,合法
        int c = b;
        //將int類型賦值給long類型,合法
        long d = c;
        //將long類型賦值給float類型,合法
        float e = d;
        //將float類型賦值給double類型,合法
        double f = e;
​
        //由於自動轉換時,會提升數據類型,所以變量e的值已經不是1了,而是1.0,所以此處輸出1.0
        System.out.println(e);
        
        //雖然變量f是雙精度浮點,但是因爲它的值是由變量e而來,所以這裏其實f的值是1.00,
        //只不過我們沒有指定格式,Java爲我們省略了最後的一個0,所以這裏也輸出1.0
        System.out.println(f);
​
        /*
        *   以上賦值鏈說明,數據類型可以向下兼容,而且可以跨層級兼容
        *   比如double兼容float,而float又兼容long,long又兼容int……
        *   以此類推,所以double兼容所有的數值類型,其他的向下兼容同理。
        * */
    }
}

上面是向下兼容,如果我們要向上兼容呢?比如將一個int類型的變量賦值給short類型的變量,這就需要short兼容int,屬於向上兼容。

這就需要我們手動轉型,也叫做強制轉換。我們只需要在值的前面用英文的小括號說明我們要轉換的類型,就可以實現強制轉換

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        //使用語法進行強制轉換:(轉換的類型)
        short b = (short) a;
        System.out.println(b);
    }
}

如果要將float或者double轉換爲整型的int、long等,會丟掉小數點後的精度:

public class Hello {
​
    public static void main(String[] args) {
        double a = 5.3;
        //將浮點型轉爲整型
        int b = (int) a;
        
        // 輸出5。
        // 注意這裏不是四捨五入,只是簡單的丟掉小數點之後的部分,
        // 就算a的值是5.9,也會輸出5
        System.out.println(b);
    }
}

另外,前面我們說過,大類型兼容小類型會自動轉換,當然我們也可以自己強制轉換,只不過編輯器會提醒你不必這麼做:

至於其他的強轉,大家可以自由的去編寫,都是一樣的道理,有問題給我發私信或者在下方評論~~~ 

 

算術運算符

Java中的算術運算符主要有:

這裏順便說一句,也有人覺得+=、-=、*=、/=、%=這幾個也是算術運算符,我覺得它們不能列到上面的表格中,畢竟它們只是一種簡潔的變身寫法,只是上面幾種的變形,在下文中也會給大家介紹。

先介紹簡單的加減乘除、取餘:

public class Hello {
​
    public static void main(String[] args) {
        int num1 = 1;
        int num2 = 2;
​
        //加,輸出3
        System.out.println(num1 + num2);
        //減,輸出-1
        System.out.println(num1 - num2);
        //乘,輸出2
        System.out.println(num1 * num2);
        //除,取商,輸出0
        System.out.println(num1 / num2);
        //取餘,輸出1
        System.out.println(num1 % num2);
    }
}

 

有趣的是,算術表達式的結果,會向表達式中更高級的數據類型轉型,什麼意思呢?看一段代碼:

 

什麼?short類型不就是整型嗎?整型進行+1操作,有毛病嗎?

原因是,Java當中所有的整數,默認是int類型,就像浮點數默認是double一樣。語句a = a + 1中的1,是一個整數,整數默認是int類型,雖然a是short類型,但整體的a + 1這個算術表達式的運算結果就被提升爲了int。雖然結果都是整數2,但它是一個int類型的2而不是short類型的2,等號右邊是int,左邊是short,顯然要進行強轉,我這麼說大家懂了嗎?

所以改成以下代碼即是正確的,用括號將表達式括起來,提高優先級,再強轉:

 

 

再舉一個例子,以下代碼是正確的:

 

雖然表達式a = a + 1中的1是int型,但是這裏的a是long類型的,最後的結果會向類型更大的轉換,也就是說會自動提升爲long類型,所以是可行的。

同理,以下代碼就是不可行的,就像我們上面說的那樣,右邊的運算結果提升爲了long類型,左邊卻是int,顯然是不行的:

 

 

基於上面所說的數據類型提升,顯然存在以下結論:

當算術表達式中存在浮點數時,會提升爲默認的浮點類型double,特別標註的除外。

什麼意思呢?看一段代碼:

 

整型提升爲浮點型,我覺得很容易理解吧,你加了一個小數,運算結果爲2.6,2.6當然是浮點型了!只不過Java中默認的浮點型是double,所以提升爲了double。

如果我們將小數特殊標註爲float,你就可以用float類型去接收運算結果:

 

乘、除、取餘都一個道理,不再舉例了。下面重點說說++、--,即自增和自減。

 

有趣的++、--

++和--是自增、自減運算符,值的變化幅度是1,即自增1、自減1:

public class Hello {
​
    public static void main(String[] args) {
        int a = 0;
        //自增1,等價於a = a + 1
        a++;
    }
}

自增和自減運算符只能直接作用於變量的身上,不能寫在具體的數字身上,以下代碼是錯誤的:

 

 

有趣的是,++、--可以寫在變量的前面,也可以寫在變量的後面,不同的地方有不同的執行機制,大家思考一下,以下代碼的輸出結果:

public class Hello {
​
    public static void main(String[] args) {
        int a= 1;
        //a++
        System.out.println(a++);
        //++a
        System.out.println(++a);
        
        System.out.println(a);
    }
}

最後的輸出結果是:

 

 

爲什麼是1、3、3呢?這是因爲,自增或自減寫在變量之後,程序會先使用變量的值,再重新計算賦值;自增或自減寫在變量之前,程序先重新計算賦值,再進行使用。區別就是先使用、還是先計算,++或--寫在前面是先計算、再使用,寫在後面是先使用、再計算

 

所以上述代碼,在第6行先使用變量a的值進行打印,此時的變量值是1,所以打印出了1,緊接着將變量a的值自增1,變成了2;在第8行,由於++寫在了變量之前,要先進行計算、再使用,先將a的值自增1,變成了3,然後再進行打印,所以打印出了3;最後的打印語句沒有自增或自減,所以也打印3

 

再來一個例子:

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = ++a;
        int c = a++;
​
        System.out.println(b);
        System.out.println(c);
        System.out.println(a);
    }
}

上述代碼的打印結果是2、2、3,在第5行先將a的值+1變成2,再賦值給b,所以b的值是2;然後在第6行,先使用a的值2賦給變量c,再將a的值+1變成3,所以此時c的值是2,a的值是3,故而我們的打印結果是2、2、3,大家明白了嗎?

而且,自增、自減運算符有隱式的數據類型轉換,以下代碼正確:

 

 

自減運算符--也是一個道理,這裏我就不再舉例了。

 

“特殊”的算術運算符

接下來就介紹幾個特殊的算術運算符:+=、-=、*=、/=、%=。

它們是基本算術運算符的變形,我們就拿+=舉例:

public class Hello {
​
    public static void main(String[] args) {
        int a= 1;
        //意思是在a的基礎上,+2
        a += 2;
        //輸出3
        System.out.println(a);
    }
}

​以上代碼中的算術表達式a += 2,等價於a = a + 2,是一種簡寫而已。那麼同理,a -= 2等價於a = a - 2,a *= 2等價於a = a * 2……不再舉例。

需要注意的是,同自增、自減運算符一樣,此類運算符也有隱式的類型轉換,所以以下代碼是可行的:

 

“+”在字符串中的應用

“+”在數值類型的計算中表示加法,它還有一種用法,就是在String類型的字符串中表示拼接:

public class Hello {
​
    public static void main(String[] args) {
        String str = "你好,";
        //使用+進行拼接
        str = str + "Java開發之旅";
        //輸出  你好,Java開發之旅
        System.out.println(str);
    }
}

同樣的,既然“+”可以用,“+=”也可以用:

public class Hello {
​
    public static void main(String[] args) {
        String str = "你好,";
        //等價於 str = str + "Java開發之旅";
        str += "Java開發之旅";
        //輸出  你好,Java開發之旅
        System.out.println(str);
    }
}

而且,String類型是更大的數據類型,它可以使用“+”兼容所有的8種基本類型,表達式的結果會被提升爲String字符串,注意只能是“+”進行字符串的拼接,其餘的乘除減法等等都是不成立的:

public class Hello {
​
    public static void main(String[] args) {
        //輸出  a的值是:1
        int a = 1;
        String str = "a的值是:" + a;
        System.out.println(str);
        
        //輸出  b的值是:5.6
        double b = 5.6;
        str = "b的值是:" + b;
        System.out.println(str);
        
        //由於這裏的1是字符串的“1”,所以雖然用了+=2,但只是字符串的拼接,輸出字符串的“12”
        str = "1";
        str += 2;
        System.out.println(str);
    }
}

在後面我們講到面向對象的時候,會專門用一篇文章來講解String類,因爲現在大家對類、方法、常量還沒有概念,我們會逐漸深入。

 

算術運算符的優先級

Java當中的運算符有3種,算術運算符、關係運算符、邏輯運算符,在講完這三種運算符之後會給大家彙總一個表。

基本的算術運算符,和我們在數學裏的習慣是一樣的:()、*、/、%、+、-,括號最大,往右遞減之。

那+=、-=、*=……這些特殊的運算符,和基本的運算符結合起來是怎樣的優先級呢?這裏就留給大家思考的空間,大家下去自己嘗試一下、總結一下,想想下面的執行結果:

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = a += 6 * 2 - 1;
        System.out.println(b);
    }
}

當然了,這裏只是讓大家總結,真正的開發中如果寫成這樣,會被同事罵死的,我們要用括號來提高優先級,這樣代碼的可讀性也更高:

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = a += 6 * (2 - 1);
        System.out.println(b);
    }
}
public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = (a += 6) * 2 - 1;
        System.out.println(b);
    }
}
public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = a += (6 * 2) - 1;
        System.out.println(b);
    }
}

小結

以上就是第5節課的內容,你懂了嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章