Java Integer的默認(rèn)緩存特性

發(fā)現(xiàn)問題

項(xiàng)目里有發(fā)現(xiàn)“神奇”的代碼,先不考慮代碼邏輯以及實(shí)現(xiàn)方法是否合理,原來代碼實(shí)現(xiàn)大致是這樣:

## department 對(duì)象
public class Department{
   private  Integer departmentId;
   private  String  departmentName;
   private Integer  pDepartmentId;
   
   private List<user> departmentMember;
   ## 省略get\set方法
}
## user 對(duì)象
publci class User{
    private Integer userId;
    private String name;
    
    ##所屬部門編號(hào)
    private Integer departmentId;
    
    ## 省略get/set方法
}
  ## 組織部門人員信息
  
  ## 獲取部門信息
  List<Department> departments= departmentService.getAllDepartments();
  
  ## 獲取人員信息
  List<User> users=userService.getAllUsers();
  
  ## 迭代,拼接數(shù)據(jù)
  for(Department dep:departments){
      for(User user:users){
          //坑點(diǎn)
          if(user.getDepartmentId() == dep.getDepartmentId()){
              if(null == dep.getDepartmentMember() ){
                  dep.setDepartmentMember(new ArrayList<User>());
              }else{
                  dep.getDepartmentMember().add(user);
              }
          }
      }
  }
 

坑點(diǎn),看到偽碼大概都能知道了,就是Integer的比較,應(yīng)該使用 equals() 或者 轉(zhuǎn)換成 int進(jìn)行比較,但這里隱藏了Java
的一個(gè)特性,使得 == 的運(yùn)行符合預(yù)期,不正常變得正常了?。?!但是“正常”還得結(jié)合特定的數(shù)據(jù),造來:

CREATE TABLE `b_department` (
  `department_id` int(11) NOT NULL AUTO_INCREMENT,
  `department_name` varchar(50) DEFAULT NULL,
  `p_department_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`department_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

如果部門數(shù)據(jù)比較少,數(shù)據(jù)庫中的department_id剛好都小于127,程序運(yùn)行的符合預(yù)期?。?! Why???!

在這里:

 為了節(jié)省內(nèi)存,對(duì)于下列包裝對(duì)象的兩個(gè)實(shí)例,當(dāng)它們的基本值相同時(shí),他們總是 ‘相等’的  
 Boolean  
 Byte  
 Character, \u0000 - \u007f(7f是十進(jìn)制的127)  
 Integer, -128 — 127  

延伸 :JVM通過參數(shù)調(diào)整包裹對(duì)象緩存大小

使用Oracle/Sun JDK 6,在server模式下,使用-XX:AutoBoxCacheMax=NNN參數(shù)即可將Integer的自動(dòng)緩存區(qū)間設(shè)置為[-128,NNN]

注意: 區(qū)間的下界固定在-128不可配置,在client模式下該參數(shù)無效。

測(cè)試代碼:

public class TestIntegerCache {  
    public static void main(String[] args) {  
        Integer a = 1024;  
        Integer b = 1024;  
        System.out.println(a == b);  
          
        Integer c = 1025;  
        Integer d = 1025;  
        System.out.println(c == d);  
          
        Integer e = 20000;  
        Integer f = 20000;  
        System.out.println(e == f);  
    }  
}  
shell >java TestIntegerCache  
false  
false  
false  
  
shell >java -server TestIntegerCache  
false  
false  
false  
  
shell >java -Djava.lang.Integer.IntegerCache.high=1024 TestIntegerCache  
true  
false  
false  
  
shell >java -server -Djava.lang.Integer.IntegerCache.high=1024 TestIntegerCache  
true  
false  
false  
  
shell >java -Djava.lang.Integer.IntegerCache.high=1025 TestIntegerCache  
true  
true  
false  
  
shell >java -server -Djava.lang.Integer.IntegerCache.high=1025 TestIntegerCache  
true  
true  
false  
  
shell >java -XX:AutoBoxCacheMax=1024 TestIntegerCache  
Unrecognized VM option 'AutoBoxCacheMax=1024'  
Could not create the Java virtual machine.  
  
shell >java -server -XX:AutoBoxCacheMax=1024 TestIntegerCache  
true  
false  
false  
  
shell >java -server -XX:AutoBoxCacheMax=1025 TestIntegerCache  
true  
true  
false  
  
shell >java -server -XX:+AggressiveOpts TestIntegerCache  
true  
true  
true  

參考文檔 : Java Integer(-128~127)值的==和equals比較產(chǎn)生的思考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,642評(píng)論 18 399
  • Java8張圖 11、字符串不變性 12、equals()方法、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,895評(píng)論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,538評(píng)論 19 139
  • 如果我喜歡你 我會(huì)主動(dòng)往你的方向走幾步再走幾步 我會(huì)明明白白的表達(dá)我的真心 如果你看見我走過來了 懷著相同的熱忱和...
    四月四月April閱讀 434評(píng)論 0 0
  • 寧靜的老街 久眠于此 石板街 舊茶館 溺于深海 那個(gè)遠(yuǎn) 方 心有詩,腳下有遠(yuǎn)方。
    天藍(lán)Y閱讀 422評(píng)論 2 3

友情鏈接更多精彩內(nèi)容