孫悟空的七十二變是那般?–java類型的七十二變揭秘
- 2019 年 10 月 5 日
- 筆記
故事背景
在《西遊記》原著第六回,孫悟空大鬧天宮反下界,玉帝派十萬天兵圍剿,卻被打得落花流水。玉帝不得不放下架子,請自己外甥二郎神回來支援。孫悟空與二郎神本事差不多,兩人斗得不分勝負,但二郎神有梅山六兄弟助陣,而孫的陣營只是烏合之眾。兩人戰鬥正酣時,孫悟空聞後方陣營攻破,猴子被打散,心中發慌敗下陣來。
為了逃脫梅山六兄弟的圍追堵截,孫悟空搖身一變,變作一個麻雀,飛在樹桃頭釘住。這個變化太low了,二郎神一眼就識破假象,立即變成餓鷹撲了過來。孫悟空只得又變成大鶿老衝天而起,二郎神則變成大海鶴,鑽上雲宵來嗛……
幾經鬥法,孫悟空最後變成一座土地廟,牙齒作門扇,舌頭變菩薩,眼睛變窗欞,但尾巴卻不好收拾,只得豎在後面,變成一根旗竿。這個變化迷惑性很大,一般神仙還真看不破。不料二郎神趕到,見一根旗竿立在後面,頓時笑了:“是這猢猻了!他今又在那裡哄我。我也曾見廟宇,更不曾見一個旗竿豎在後面的。斷是這畜生弄誼!他若哄我進去,他便一口咬住。我怎肯進去?等我掣拳先搗窗欞,後踢門扇!”孫悟空一聽,媽媽呀,這二郎神好狠!“門扇是我牙齒,窗欞是我眼睛;若打了牙,搗了眼,卻怎麼是好?”於是趕緊收了法相,逃命去了。
這七十二變的最大缺陷是:若是變飛禽、走獸、花木、器皿、昆蟲之類,可以連身子一起變;但如果變人物,卻只是頭臉變了,身子變不過來,還有一身黃毛,兩塊紅股,一條尾巴。原因:七十二變化本身就是人研製出來的,也是為人量身打造的,故孫悟空學會後會存在缺陷。
java中的七十二變
我們看一下,java的七十二般變化吧!
public class Multicast{ public static void main (String[] args){ System.out.println((int)(char)(byte) -1); } }
上面的程式以int 數值-1 開始,然後從int轉型為byte,之後轉型為char,最後轉型回int。第一個轉型將數值從32 位窄化到了8 位,第二個轉型將數值從8 位拓寬到了16 位,最後一個轉型又將數值從16 位拓寬回了32 位。這個數值最終是回到了起點嗎?
是不是想起了《看我七十二變》:
看我七十二變
今天新鮮改變再見
美麗極限愛漂亮沒有終點
追求完美的境界
人不愛美天誅地滅
彆氣餒舊觀念拋到一邊
現在就開始改變
麻雀也能飛上青天
運行看結果吧
65535
為什麼會這樣呢?我們將程式一步步分開來看:
public static void main (String[] args){ int i=-1; byte b=(byte)-1; //1 char c=(char)b; //2 int r=(int)c; //3 System.out.println(r); }
第一步:int轉byte
byte b=-1 窄化後沒有改變值
第二步:byte轉char
從byte 到char 的轉型稍微麻煩一點,因為byte 是一個有符號類型,而char是一個無符號類型。在將一個整數類型轉換成另一個寬度更寬的整數類型時,通常是可以保持其數值的,但是卻不可能將一個負的byte 數值表示成一個char。因此,從byte 到char 的轉換被認為不是一個拓寬原始類型的轉換,而是一個拓寬並窄化原始類型的轉換(widening and narrowing primitive conversion):byte 被轉換成了int,而這個int 又被轉換成了char
char c=65535//符號擴展
第三步:char轉int
int r=65535//零擴展
因為byte 是一個有符號的類型,所以在將byte 數值-1 轉換成char 時,會發生符號擴展。作為結果的char 數值的16 個位就都被置位了,因此它等於2的16次方-1,即65535。
從char 到int 的轉型也是一個拓寬原始類型轉換,它將執行零擴展而不是符號擴展。作為結果的int 數值也就成了65535,
這正是程式列印出的結果。
深入:java如何七十二變?
jls-5強制類型轉換,定義標識如下:
– 表示不運行任何強制類型轉換
≈ 表示標識抓獲(§5.1.1)
ω 表示拓寬基本類型轉換 (§5.1.2)
η 表示窄化基本類型轉換 (§5.1.3)
ωη 表示拓寬和窄化類型轉換 (§5.1.4)
⇑ 表示拓寬引用類型轉換 (§5.1.5)
⇓ 表示窄化引用類型轉換(§5.1.6)
⊕ 表示裝箱轉換 (§5.1.7)
⊗表示拆卸類型轉換 (§5.1.8)
更詳細的資料請參照JSL5描述,鏈接地址見參考資料【3】
參考資料
【1】https://baike.baidu.com/tashuo/browse/content?id=1275b5b5f23ff153017f164c&fr=qingtian&lemmaId=11061
【2】https://baike.baidu.com/item/%E4%B8%83%E5%8D%81%E4%BA%8C%E5%8F%98/11061?fr=aladdin#2_2
【3】https://docs.oracle.com/javase/specs/jls/se12/html/jls-5.html
【4】java解惑