java中數據類型
基本類型:int、short、long、double、float、boolean、char 注意:並無String的基本類型,存在於棧中
包裝類數據:integer、String、Double等包裝類,存在於堆java
第一個概念:
自動裝箱和自動拆箱:
當你用基本類型的值給包裝類賦值時,就會發生基本類型向包裝類型的轉換:「自動裝箱」
當你用包裝類的值給基本類型的值進行賦值時,系統也會自動的將包裝類轉換爲基本類型:自動裝箱緩存
第二個實例:Integer、double、float的緩存app
Integer、double、float的緩存cache:性能
integer:在 Java 5 中,爲 Integer 的操做引入了一個新的特性,用來節省內存和提升性能。整型對象在內部實現中經過使用相同的對象引用實現了緩存和重用。上面的規則適用於整數區間 -128 到 +127,ui
並且須要注意的是integer類型字面量賦值時纔會緩存,而使用構造器建立的 Integer 對象不能被緩存。spa
好比:code
Integer abc=new Integer(45); //不會有緩存這一項操做
其餘緩存的對象對象
這種緩存行爲不只適用於Integer對象。咱們針對全部整數類型的類都有相似的緩存機制。blog
有 ByteCache 用於緩存 Byte 對象內存
有 ShortCache 用於緩存 Short 對象
有 LongCache 用於緩存 Long 對象
有 CharacterCache 用於緩存 Character 對象
Byte,Short,Long 有固定範圍: -128 到 127。對於 Character, 範圍是 0 到 127。除了 Integer 能夠經過參數改變範圍外,其它的都不行。
System.out.println("自動裝箱和自動拆箱"); Integer a=1; Integer b=2; Integer c=3; Integer d=3; Integer e=321; Integer f=321; Long g=3L; System.out.println(c==d);//true //緩存 System.out.println(e==f);//false //超出緩存的範圍 System.out.println(c.equals(a+b));//true 第一步進行了自動拆箱,而後比較兩個int的值 System.out.println(c==(a+b));//true //算術運算時,進行自動拆箱,c變爲int,a+b 變爲int 值,而後比較兩個int值 System.out.println(g==(a+b));//true //首先對a+b進行自動拆箱爲int,而後涉及隱式類型轉換,int-->long, System.out.println(g.equals(a+b));//false a+b進行拆箱, int A=1; Integer B=1; System.out.println(B.equals(A)); //true System.out.println(B==A);//true
String:是一個特殊的包裝類數據
String Str="asd";建立String類型須要通過三個步驟
1.首先在常量池中查找是否存在內容爲"abc"的字符串對象
2.若是不存在則在常量池中建立一個"abc"的字符串對象,並讓str引用該對象
3.若是存在則直接讓str引用該對象
String string="asdas"; String string1="asdas"; System.out.println(string==string1);\\true
String str = new String("abc")建立實例的過程
1首先定義一個str的String類型的引用並存放在棧中
2在字符串常量池中查看是否存在內容爲"abc"字符串對象
3若存在則跳過這個步驟,若不存在,則在字符串常量池中建立一個內容爲"abc"的字符串對象
4執行new操做,在堆中建立一個指定的對象"abc",這裏堆的對象是字符串常量池「abc」對象的一個拷貝對象
5讓str指向堆中「abc」這個對象(也就是存儲這個對象的在堆中的地址)
情景一:
java虛擬機(JVM)中,存在着一個字符串常量池,其中保存着不少String對象
而且能夠被共享使用,所以它提升了效率,因爲String類時final的 ,它的值一經建立就不可改變。
字符串池由String 類維護,咱們能夠調用intern()方法來訪問字符串池
String S1="Abc"; //字符串建立了一個對象 String S2="Abc"; //"Abc"在字符串池存在,便生成一個對象S2指向"Abc" System.out.println(S1==S2);//true System.out.println(""+S1.equals(S2));//true
情景二:
String S3=new String("Abc"); //字符串池生成一個「abc」的對象,堆中生成一個指向字符串「abc」的對象, 而且生成一個S3的引用指向堆中的對象 String S4=new String("Abc"); //字符串池中已經存在「abc」,在堆中生成一個新對象,生成一個指向堆中對象的引用S4 S4==S3 //false 堆中以及字符串池中的地址不相同
情景三;intern()方法能夠返回該字符串在常量池中的對象的引用
String str1 = "abc"; String str2 = newString("abc").intern(); System.out.println(str1==str2); //true
情景四:」假「改變,真生成:看似改變了,其實時真的生成了
String str1 = "abc"; String str2 = "abc"; str1 = "bcd"; //String引用改變指向,指向了「bcd」 //當JVM發如今常量池中沒有存放該值的地址,便開闢這個地址,並建立了一個對象, System.out.println(str1 + "," + str2); //bcd, abc System.out.println(str1==str2); //false
情景五:宏變量、宏代替的使用
String str1 = "abc"; final String str2 = "ab"; String str3 = str2+"c"; System.out.println(str1==str3); // true String str1 = "abc"; String str2 = "ab"; String str3 = str2+"c"; System.out.println(str1==str3); // false
涉及到str2是變量,str3不能生成宏代替,先是生成一個StringBuilder,而後append(str2).append("c")
而後讓str3指向StringBuilder.toString()返回的對象
String S3=new String("Abc");//字符串池生成一個「abc」的對象,堆中生成一個指向字符串「abc」的對象,而且生成一個S3的引用指向堆中的對象String S4=new String("Abc");//字符串池中已經存在「abc」,在堆中生成一個新對象,生成一個指向堆中對象的引用S4S4==S3 //false 堆中以及字符串池中的地址不相同