[短文速读] a=a+b和a+=b的区别
前言
短文速讀,這將是一個系列文章。自己寫了很多文章,也看了很多文章。發(fā)現(xiàn)很多都是收藏不看系列。當(dāng)然有時間的時候,的確會把收藏的文章找出來好好的學(xué)習(xí)一番。但是大多數(shù)文章仿佛石沉大海,失去了應(yīng)有的價值。
所以萌生了這個系列的想法,系列文章的特點:以一些日常開發(fā)中不起眼的基礎(chǔ)知識點為內(nèi)核,圍繞此包裹通俗易懂的文字。盡量用少思考的模式去講述一個知識。讓我們能夠真正在碎片化的時間里學(xué)到東西!
出場角色
小A:剛踏入Java編程之路...
MDove:一個快吃不上飯的Android開發(fā)...
正題
小A:MDove,最近我有一個不成熟的小疑問,不知道當(dāng)講不當(dāng)講。
MDove:不成熟那就別問了...
小A:額錯了,額真滴錯了。額從一開始就不應(yīng)該學(xué)Java...
MDove:問、問、問...
小A:a=a+b和a+=b。這倆者有什么區(qū)別呀?沒看出來有什么區(qū)別啊!
MDove:你所說的沒區(qū)別,是這樣吧?
int a = 1; int b = 2; a = a + b; a += b;MDove:那你有沒有換過別的寫法呢?比如把b的類型變一下:
float b = 2F;MDove:怎么樣,看出來效果了吧。沒看出來??OK,那我就貼上效果:
編譯不能通過MDove:這樣就能看明白了吧?b提升了類型之后。會發(fā)現(xiàn)a = a + b是沒辦法編譯通過的,需要強制類型轉(zhuǎn)換才可以。但是我們的a + = b卻可以,這是為什么呢?其實很簡單。讓我們反編譯一下這個class文件,就可以很清晰的給出答案:
public void fun() { int a = 1;float b = 2F;a += b; }// 反編譯class的內(nèi)容 public void fun() {byte var1 = 1;float var2 = 2.0F; int var10000 = (int)((float)var1 + var2); }MDove:所以它們二者的區(qū)別就很清楚了吧?在這種a比b類型范圍要小的情況下。a = a + b;需要強制類型轉(zhuǎn)換,也就是我們常寫的:a = (int) (a+b);而我們的a += b;被我們的編譯器在編譯期做了一些小手腳。也就是編譯器幫我們進行了強制類型轉(zhuǎn)化。
小A:原來是這樣,那強制類型轉(zhuǎn)換會帶來什么問題呢?
MDove:解答這個問題,讓我們先來看一張圖:
imageMDove:強制類型轉(zhuǎn)化,一般會帶來精度丟失的問題。這里float的范圍太大,我們就用byte和short來演示,強制類型帶來的問題:
public void fun() {byte a = 1;short b = 127;a=(byte) (a+b);System.out.println(a); }MDove:System打出的內(nèi)容,應(yīng)該知道是什么吧?沒錯是-128。強制類型帶來的問題一目了然了吧。
小A:怎么會是-128呢?
MDove:OK,接下來,我來解釋一下,為什么會是-128這么一個奇怪的數(shù)字。首先,我們都知道基本類型在堆中所占的字節(jié)如下表。
小A:不對呀?我記得基本類型是存放在棧中的呀?
MDove:這種說法并不錯,但不全面。存放在堆中還是在棧中,是取決于這個變量聲明的位置。如果是局部變量,則會存放在棧幀中。但是如果是成員變量(全局變量),那么就會存放在堆中。此外存放在棧中,基本類型所占的字節(jié)是固定:如果是32位計算機那么就是4字節(jié);64位便是8字節(jié)。
| byte | 1字節(jié) |
| short | 2字節(jié) |
| int | 4字節(jié) |
| long | 8字節(jié) |
| char | 2字節(jié) |
| float | 4字節(jié) |
| double | 8字節(jié) |
MDove:解釋完所占字節(jié)的問題,咱們繼續(xù)。由上邊可知byte占1字節(jié),那么也就是8位,如果每一位都為1(11111111),那么理論上就是它所能表示的最大內(nèi)容。
小A:那應(yīng)該是255呀!
MDove:實際不然,因為正負(fù)的原因,計算機中使用補碼的形式表示二進制,高1位表示符號位(0為正,1為負(fù))。因此對于8位來說,最大只能是01111111,也就是127。(0表示它為正)
MDove:而我們剛才的那個計算byte a = 1; short b = 127; a=(byte) (a+b);不考慮類型轉(zhuǎn)換,那么a+b妥妥的等于128。并且對于所占2字節(jié)的short來說那就是00000000 10000000。但是我們強制類型轉(zhuǎn)化成了byte,這時做了一件事情,那就是高1字節(jié)的內(nèi)容全部砍掉,也就是只剩下了10000000。
MDove:按我們剛才所說,高1位的內(nèi)容表示正負(fù)。1為負(fù)。
小A:!!!如果1為負(fù),那System.out應(yīng)該是0才對啊。
MDove:一看你二進制就沒有好好學(xué)。對于含有補碼形式的10000000,我們要用補碼的方式去計算。計算套路如下:高1位為1,那么這是數(shù)就是負(fù)數(shù)。想要知道是負(fù)幾,我們需要將10000000按位取反,也就是01111111。還沒完,此時還要再加1,也就是10000000。現(xiàn)在得到的這個數(shù)是幾,那么就是負(fù)幾,10000000是十進制的128,因此補碼形式的10000000也就是:-128。
MDove:這樣解釋是不是就知道強制類型轉(zhuǎn)換帶來的問題,以及為什么強制類型轉(zhuǎn)化后的byte變成了-128了吧。
小A:好難學(xué)...我想回家種地...
小A媽:崽,別學(xué)編程啦,趕緊回家收玉米了。
劇終
這里是一幫應(yīng)屆生共同維護的公眾號,內(nèi)容是我們在從應(yīng)屆生過渡到開發(fā)這一路所踩過的坑,以及我們一步步學(xué)習(xí)的記錄,如果感興趣的朋友可以關(guān)注一下,一同加油,一同努力!!
個人公眾號:IT面試填坑小分隊總結(jié)
以上是生活随笔為你收集整理的[短文速读] a=a+b和a+=b的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7分钟理解JS的节流、防抖及使用场景
- 下一篇: WinForm读取指定的config文件