1. 程式人生 > >[厲害了,我的JAVA基礎](四)int 和 Integer 有什麼區別?Integer的值快取範圍

[厲害了,我的JAVA基礎](四)int 和 Integer 有什麼區別?Integer的值快取範圍

1 int與integer的基本使用對比

(1)Integer是int的包裝類;int是基本資料型別;
(2)Integer變數必須例項化後才能使用;int變數不需要;
(3)Integer實際是物件的引用,指向此new的Integer物件;int是直接儲存資料值 ;
(4)Integer的預設值是null;int的預設值是0。

2 int與Integer的深入對比

(1)由於Integer變數實際上是對一個Integer物件的引用,所以兩個通過new生成的Integer變數永遠是不相等的(因為new生成的是兩個物件,其記憶體地址不同)。

Integer i = new Integer(100);
Integer j = new Integer(100);
System.out.print(i == j); //false

(2)Integer變數和int變數比較時,只要兩個變數的值是向等的,則結果為true(因為包裝類Integer和基本資料型別int比較時,java會自動拆包裝為int,然後進行比較,實際上就變為兩個int變數的比較)

Integer i = new Integer(100);
int j = 100;
System.out.print(i == j); //true

(3)非new生成的Integer變數和new Integer()生成的變數比較時,結果為false。(因為非new生成的Integer變數指向的是java常量池中的物件,而new Integer()生成的變數指向堆中新建的物件,兩者在記憶體中的地址不同)

Integer i = new Integer(100);
Integer j = 100;
System.out.print(i == j); //false

(4)對於兩個非new生成的Integer物件,進行比較時,如果兩個變數的值在區間-128到127之間,則比較結果為true,如果兩個變數的值不在此區間,則比較結果為false

Integer i = 100;
Integer j = 100;
System.out.print(i == j); //true

Integer i = 128;
Integer j = 128;
System.out.print(i == j); //false

  對於第4條的原因: java在編譯Integer i = 100 ;時,會翻譯成為Integer i = Integer.valueOf(100)。而java API中對Integer型別的valueOf的定義如下,對於-128到127之間的數,會進行快取,Integer i = 127時,會將127進行快取,下次再寫Integer j = 127時,就會直接從快取中取,就不會new了。

public static Integer valueOf(int i){
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high){
        return IntegerCache.cache[i + (-IntegerCache.low)];
    }
    return new Integer(i);
}

3 Java兩種資料型別

3.1 Java兩種資料型別分類

原始資料型別,分為boolean,byte,in,char,long,short,double,float
引用資料型別 ,分為陣列,類,介面

3.2 Java為每個原始型別提供了封裝類

為了程式設計的方便還是引入了基本資料型別,但是為了能夠將這些基本資料型別當成物件操作,Java為每 一個基本資料型別都引入了對應的包裝型別(wrapper class),int的包裝類就是Integer,從Java 5開始引入了自動裝箱/拆箱機制,使得二者可以相互轉換。

原始型別: booleancharbyteshort,int,long,float,double
封裝類型別:Boolean,Character,ByteShortIntegerLong,Float,Double

4、 基本解析

4.1 自動裝箱:將基本資料型別重新轉化為物件

    public class Test {  
        public static void main(String[] args) {  
            //宣告一個Integer物件
            Integer num = 9;
            //以上的宣告就是用到了自動的裝箱:解析為:Integer num = new Integer(9);
        }  
    }  

9是屬於基本資料型別的,原則上它是不能直接賦值給一個物件Integer的,但jdk1.5後你就可以進行這樣的宣告。自動將基本資料型別轉化為對應的封裝型別,成為一個物件以後就可以呼叫物件所宣告的所有的方法。

4.2 自動拆箱:將物件重新轉化為基本資料型別

 public class Test {  
        public static void main(String[] args) {  
            //宣告一個Integer物件
            Integer num = 9;
            //進行計算時隱含的有自動拆箱
            System.out.print(num--);
        }  
    }  

因為物件時不能直接進行運算的,而是要轉化為基本資料型別後才能進行加減乘除。

對比:

/裝箱
Integer num = 10;
//拆箱
int num1 = num;

5、深入解析

5.1 情況描述

   public class Test {  
        public static void main(String[] args) {  
            //在-128~127 之外的數
            Integer num1 = 128;   Integer num2 = 128;           
            System.out.println(num1==num2);   //false

            // 在-128~127 之內的數 
            Integer num3 = 9;   Integer num4 = 9;   
            System.out.println(num3==num4);   //true
        }  
    }  
1

解析原因:歸結於java對於Integer與int的自動裝箱與拆箱的設計,是一種模式:叫享元模式(flyweight)。
加大對簡單數字的重利用,Java定義在自動裝箱時對於值從–128到127之間的值,它們被裝箱為Integer物件後,會存在記憶體中被重用,始終只存在一個物件。
而如果超過了從–128到127之間的值,被裝箱後的Integer物件並不會被重用,即相當於每次裝箱時都新建一個 Integer物件。

5.2 Integer原始碼解析

給一個Integer物件賦一個int值的時候,會呼叫Integer類的靜態方法valueOf,原始碼如下:

public static Integer valueOf(String s, int radix) throws NumberFormatException {
        return Integer.valueOf(parseInt(s,radix));
    }
public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

IntegerCache是Integer的內部類,原始碼如下:

  /**
      * 快取支援自動裝箱的物件標識語義
      * -128和127(含)。
      *
      * 快取在第一次使用時初始化。 快取的大小
      * 可以由-XX:AutoBoxCacheMax = <size>選項控制。
      * 在VM初始化期間,java.lang.Integer.IntegerCache.high屬性
      * 可以設定並儲存在私有系統屬性中
     */
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

相關推薦

[厲害JAVA基礎]int Integer 什麼區別Integer快取範圍

1 int與integer的基本使用對比 (1)Integer是int的包裝類;int是基本資料型別; (2)Integer變數必須例項化後才能使用;int變數不需要; (3)Integer實際是物件的引用,指向此new的Integer物件;i

java基礎 Java種引用強弱軟虛用到的場景

強引用: 強引用不會被GC回收,並且在java.lang.ref裡也沒有實際的對應型別,平時工作接觸的最多的就是強引用。 Object obj = new Object();這裡的obj引用便是一個強引用。 如果一個物件具有強引用,那就類似於必不可少的生活用品,垃

Java基礎

抽象類 使用 發生 註意 方法 類實例化 類方法 內容 大寫字母 一、方法 1、方法的定義   方法也叫函數,就是一個能獨立完成某個功能的一段代碼。方法可以看作一個整體。 語法: 修飾符 返回類型 方法名字(數據類型 變量名,數據類型 變量名,……[形式參數(0個到n

JAVA基礎面試題

Java基礎 Java程序員面試 面試題: 構造代碼塊,構造方法,靜態代碼的優先級? 靜態代碼塊>構造代碼塊>構造方法 面試題: overload和override的區別?overload:方法重載方法名一樣,參數不同,和返回值沒有關系參數不同:1)參數個數不同2)參數類型不同over

java基礎陣列

陣列是儲存多個變數的容器(集合) 本章內容是一維陣列的建立和小demo /* * 陣列 * 概念:1.陣列是儲存多個變數的容器(集合),且這些變數的資料型別一致 * 2.陣列既可以儲存基本資料型別,也可以儲存引用資料型別 * * */ public class Arra

java面試題——java基礎

table 生命 運行 漸變 於平 單獨使用 標記語言 prepare 新建 java基礎1.java跨平臺  由於各個操作系統的指令不完全一樣,在不同的操作系統執行不同的程序代碼,java開發了java虛擬機來屏蔽系統之間的差異,針對不同的系統安裝不同的虛擬機即可。2.i

Java基礎java連線資料庫

Java 連線 MySQL和Java 連線 Oracle資料庫的一些基本總結: 1.Java 連線 MySQL資料庫 //整體封裝寫為一個方法(後續補上) public class MysqlDemo { //引入Jdbc驅動及資料庫地址URL final String Jd

人生苦短用Python—通過Flask結合Bootstrap框架快速搭建Web應用-1

寫在前面: Flask是一個給予Python開發,依賴jinja2模板和Werkzeug WSGI服務的一個微型框架。Werkzeug用來處理Socket服務,其在Flask中被用於接受和處理http請求;Jinja2被用來對模板進行處理,將模板和資料進行渲染,返回給使用者的瀏覽器。 Boo

java基礎static修飾類

在前面的部落格中,談到了static修飾類內部變數及程式碼塊的用法,卻忽略了其用來修飾內部類的情況。 為何會有用來修飾類的用法,及所有static用法的本質是什麼?這篇文章就解釋著兩個問題。 一、內部類 如果一個類要被宣告為static的,只有一種情況,就是靜態內部類。如果在外部類宣告為

Java基礎Java類的成員變數區域性變數

在Java中,成員變數和區域性變數存在較大的差異性。首先,我們來看一下變數的分類圖: 成員變數 成員變數被分為:類屬性和例項屬性。 例項屬性:定義一個屬性時,不使用static修飾的就是例項屬性, 類屬性:定義一個屬性時,使用static修飾的是類屬性。 類屬性從這

java基礎:字串

1.String概念:字串一旦被建立就不可以更改 (1)A.==B:判斷地址;     A.equals(B):判斷A,B的內容 (2).常用方法:         長度:str.length();  

大資料之JAVA基礎:集合ArrayList

1.集合的建立1).ArrayList集合看作一個長度可變的陣列2).ArrayList<要儲存元素的資料型別> 變數名 = new ArrayList<要儲存元素的資料型別>();3).集合中儲存的元素,只能為<>括號中指定的資料型別元素

JAVA基礎13---順序選擇控制語句

 流程控制 Java中的流程控制有三類:順序控制、選擇控制和迴圈控制 順序控制語句        在Java中的程式的執行流程:         &nbs

JAVA基礎34---StringBufferStringBuilder

StringBuffer / StringBuilder 為了解決的問題:String是不可變的造成的記憶體浪費和String物件的使用效率比較低這兩個問題 StringBuffer:執行緒安全的可變字元序列,通過某些方法呼叫可以改變該序列的長度和內容。 StringBuilder

JAVA基礎60---介面與類的區別聯絡

類,介面和抽象類之間的關係以及區別與聯絡 類與類   類與介面  以及 介面與介面 的關係 類與類              

QT基礎訊號

什麼是訊號和槽?訊號和槽的作用 訊號和槽都是函式,比如按下視窗上的一個按鈕後想要彈出一個對話方塊,那麼就可以將這個按鈕的單擊訊號和我們定義的槽關聯起來,在這個槽中可以建立一個對話方塊,並且顯示它。這樣,當單擊這個按鈕時就會發射訊號,進而執行我們的槽來顯示一個對

Java基礎反射Class

一、簡介 Java反射是Java被視為動態語言的一個關鍵性質,這個機制允許程式在執行時透過Reflection APIs取得任何一個已知名稱的class的內部資訊,包括其modifiers(諸如public, static 等)、superclass(例如Object)、實現之interface

JAVA基礎過載複寫

最近開始研究Android的設計模式,主要是感覺在已經能完成大部分功能型程式碼後,感覺到了框架結構的重要性,可是在研究過程中又發現了另一個問題。自己的JAVA基礎似乎並不是太好,很多東西都停留在表面,這樣就致使自己研究設計模式遇到了很大問題。就像地基沒有打好,往

厲害的中國造@主動發力還是借力打力?——思華科技18年自主創新經驗談上篇...

點選上方藍色字關注我們~十八載執著創新雲端計算一馬當先自主可控心中念未來征途尤可期“自主可控”這

Java還要再學一遍基礎JDK1.8新特性defaultstatic

JDK1.8新特性default,static用法 在1.8以前,我們的Interface之中通常除了抽象方法別的什麼都沒有,但是從1.8引入開始Interface中還可以有具體的實現!其中所要用到的兩個非常重要的關鍵字就是:default和static