一、(四)坏怪、7
【強(qiáng)制】所有的相同類型的包裝類對(duì)象之間值的比較贝润,全部使用equals方法比較。 說(shuō)明:對(duì)于Integer var = ? 在-128至127范圍內(nèi)的賦值铝宵,Integer對(duì)象是在
IntegerCache.cache產(chǎn)生打掘,會(huì)復(fù)用已有對(duì)象,這個(gè)區(qū)間內(nèi)的Integer值可以直接使用==進(jìn)行判斷,但是這個(gè)區(qū)間之外的所有數(shù)據(jù)胧卤,都會(huì)在堆上產(chǎn)生唯绍,并不會(huì)復(fù)用已有對(duì)象,這是一個(gè)大坑枝誊,推薦使用equals方法進(jìn)行判斷况芒。
自己測(cè)試了一下,確實(shí)是這樣的叶撒,好可怕
@Test
public void testInteger() {
//測(cè)試-128 绝骚、127
Integer var1 = -129;
Integer var2 = -129;
Integer var3 = -128;
Integer var4 = -128;
Integer var5 = 127;
Integer var6 = 127;
Integer var7 = 128;
Integer var8 = 128;
// 通過(guò)以下斷言
assert var1 != var2 : "小于-128,不能使用等等";
assert var3 == var4 : "等于-128祠够,是不相等的";
assert var5 == var6 : "等于127压汪,是不相等的";
assert var7 != var8 : "大于127,是相等的";
}
一古瓤、(四)止剖、10
【強(qiáng)制】序列化類新增屬性時(shí),請(qǐng)不要修改serialVersionUID字段落君,避免反序列失敶┫恪;如果完全不兼容升級(jí)绎速,避免反序列化混亂皮获,那么請(qǐng)修改serialVersionUID值。 說(shuō)明:注意serialVersionUID不一致會(huì)拋出序列化運(yùn)行時(shí)異常纹冤。
serialVersionUID 用來(lái)表明類的不同版本間的兼容性
簡(jiǎn)單來(lái)說(shuō)洒宝,Java的序列化機(jī)制是通過(guò)在運(yùn)行時(shí)判斷類的serialVersionUID來(lái)驗(yàn)證版本一致性的。在進(jìn)行反序列化時(shí)萌京,JVM會(huì)把傳來(lái) 的字節(jié)流中的serialVersionUID與本地相應(yīng)實(shí)體(類)的serialVersionUID進(jìn)行比較雁歌,如果相同就認(rèn)為是一致的,可以進(jìn)行反序 列化知残,否則就會(huì)出現(xiàn)序列化版本不一致的異常靠瞎。
當(dāng)實(shí)現(xiàn)java.io.Serializable接口的實(shí)體(類)沒有顯式地定義一個(gè)名為serialVersionUID,類型為long的變 量時(shí)橡庞,Java序列化機(jī)制會(huì)根據(jù)編譯的class自動(dòng)生成一個(gè)serialVersionUID作序列化版本比較用较坛,這種情況下印蔗,只有同一次編譯生成的 class才會(huì)生成相同的serialVersionUID 扒最。
如果我們不希望通過(guò)編譯來(lái)強(qiáng)制劃分軟件版本,即實(shí)現(xiàn)序列化接口的實(shí)體能夠兼容先前版本华嘹,未作更改的類吧趣,就需要顯式地定義一個(gè)名為serialVersionUID,類型為long的變量,不修改這個(gè)變量值的序列化實(shí)體都可以相互進(jìn)行串行化和反串行化强挫。
關(guān)于如果使用SOA服務(wù)岔霸,如果消費(fèi)者如果和提供者依賴的實(shí)體jar包不是一個(gè)版本的話,就可能會(huì)出現(xiàn)不能反序列化俯渤。但是Dubbo默認(rèn)序列化呆细,使用hession,是直接忽略serialVersionUID的八匠。
推薦】循環(huán)體內(nèi)絮爷,字符串的連接方式,使用StringBuilder的append方法進(jìn)行擴(kuò)展梨树。 說(shuō)明:反編譯出的字節(jié)碼文件顯示每次循環(huán)都會(huì)new出一個(gè)StringBuilder對(duì)象坑夯,然后進(jìn)行append操作,最后通過(guò)toString方法返回String對(duì)象抡四,造成內(nèi)存資源浪費(fèi)柜蜈。
我們來(lái)實(shí)際看一下
反編譯字節(jié)碼命令
javap是 Java class文件分解器,可以反編譯指巡,也可以查看java編譯器生成的字節(jié)碼淑履,從而對(duì)代碼內(nèi)部的執(zhí)行邏輯進(jìn)行分析。
用法: javap <options> <classes>
其中, 可能的選項(xiàng)包括:
-help --help -? 輸出此用法消息
-version 版本信息
-v -verbose 輸出附加信息
-l 輸出行號(hào)和本地變量表
-public 僅顯示公共類和成員
-protected 顯示受保護(hù)的/公共類和成員
-package 顯示程序包/受保護(hù)的/公共類
和成員 (默認(rèn))
-p -private 顯示所有類和成員
-c 對(duì)代碼進(jìn)行反匯編
-s 輸出內(nèi)部類型簽名
-sysinfo 顯示正在處理的類的
系統(tǒng)信息 (路徑, 大小, 日期, MD5 散列)
-constants 顯示最終常量
-classpath <path> 指定查找用戶類文件的位置
-cp <path> 指定查找用戶類文件的位置
-bootclasspath <path> 覆蓋引導(dǎo)類文件的位置
##使用javap -c '不帶.class后綴的文件名'
#
public void testStrppend();
Code:
0: ldc #10 // String SH
2: astore_1
3: iconst_0
4: istore_2
5: iload_2
6: bipush 100
8: if_icmpge 37
11: new #11 // class java/lang/StringBuilder
14: dup
15: invokespecial #12 // Method java/lang/StringBuilder."<init>":()V
18: aload_1
19: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: ldc #14 // String hello
24: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
27: invokevirtual #15 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
30: astore_1
31: iinc 2, 1
34: goto 5
37: return