亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Java學(xué)習(xí)筆記-面向?qū)ο?包裝類、對象的比較、String常量池問題

Original 2016-11-18 10:34:09 482
abstract:包裝類基本類型-->包裝類byte-->Byteshort-->Shortint-->Integerlong-->Longchar-->Characterfloat-->Floatdouble-->Doubleboolean-->Boolean基本類型轉(zhuǎn)為包裝類型:自動裝箱Autoboxing:將基本類型直接賦值給包裝類變量或者Object類變

包裝類

基本類型-->包裝類

byte-->Byte

short-->Short

int-->Integer

long-->Long

char-->Character

float-->Float

double-->Double

boolean-->Boolean

基本類型轉(zhuǎn)為包裝類型:

自動裝箱Autoboxing:將基本類型直接賦值給包裝類變量或者Object類變量

包裝類型轉(zhuǎn)為包裝類型:

自動拆箱AutoUnboxing:把包裝類對象直接賦值給基本類型變量

示例:自動裝箱與自動拆箱

public class T1{  
    public static void main(String[] args) {  
        Integer inObj=13;     //自動裝箱
        Object boolObj=true;  //自動裝箱,基本類型賦值給Object類型變量
        int i=inObj;          //自動拆箱
        float f=inObj;        //自動拆箱,注意類型匹配
        System.out.println(i);
        System.out.println(f);        if (boolObj instanceof Boolean) {            boolean b=(Boolean)boolObj; //強(qiáng)制類型轉(zhuǎn)換+自動拆箱
            System.out.println(b);
        }
    }
}

字符串型的值轉(zhuǎn)為基本類型:

用包裝類的靜態(tài)的parse...()方法。注意沒有Character類,String的toCharArray()方法轉(zhuǎn)為字符數(shù)組

用包裝類的構(gòu)造器

基本類型轉(zhuǎn)為字符串

靜態(tài)方法String.valueOf();

基本變量+"";

示例:字符串轉(zhuǎn)基本類型

public class Test{  
    public static void main(String[] args) {  
        String strByte="127";
        String strShort="32767";
        String strInt="2147483647";
        String strLong="21474836478";     //加了L,用parse和new轉(zhuǎn),都會失敗
        String strFloat="3.1415F";        //加了F,用parse和new轉(zhuǎn),都能成功
        String strDouble="3.5665956565";
        String strBoolean="true";        
        byte b1=Byte.parseByte(strByte);        byte b2=new Byte(strByte);
        System.out.println(b1+"    "+b2);        short s1=Short.parseShort(strShort);        short s2=Short.parseShort(strShort);
        System.out.println(s1+"    "+s2);        int i1=Integer.parseInt(strInt);        int i2=new Integer(strInt);
        System.out.println(i1+"    "+i2);        long l1=Long.parseLong(strLong);        long l2=new Long(strLong);
        System.out.println(l1+"    "+l2);        float f1=Float.parseFloat(strFloat);        float f2=new Float(strFloat);
        System.out.println(f1+"    "+f2);        double d1=Double.parseDouble(strDouble);        double d2=new Double(strDouble);
        System.out.println(d1+"    "+d2);        boolean boo1=Boolean.parseBoolean(strBoolean);        boolean boo2=new Boolean(strBoolean);
        System.out.println(boo1+"    "+boo2);
        
    }
}

輸出

127 127
32767 32767
2147483647 2147483647
21474836478 21474836478
3.1415 3.1415
3.5665956565 3.5665956565
true true

示例:基本類型轉(zhuǎn)字符串

public class Test{  
    public static void main(String[] args) {  
        System.out.println(String.valueOf(127));
        System.out.println(String.valueOf(32767));
        System.out.println(String.valueOf(2147483647));
        System.out.println(String.valueOf(21474836478L));  //注意L
        System.out.println(String.valueOf(3.1415F));       //注意F
        System.out.println(String.valueOf(3.5665956565));
        System.out.println(String.valueOf(true));
    }
}

輸出如下:

127
32767
2147483647
21474836478 //注意沒有L
3.1415 //注意沒有F
3.5665956565
true

包裝類型與基本類型的比較

包裝類是引用類型,但可以直接用"=="跟基本類型比較

包裝類與包裝類的比較

如果包裝類對象都是通過構(gòu)造方法創(chuàng)建的:遵循對象的比較規(guī)則,即用"=="比較的是地址,用equals()比較對象的內(nèi)容

如果包裝類對象都是通過自動裝箱創(chuàng)建,且屬于[-128,127],可以用"=="比較他們的值是否相等;如果在[-128,127]之外,那么遵循對象的比較規(guī)則

通過自動裝箱和構(gòu)造方法創(chuàng)建的對象,不論是不是屬于[-128,127],都遵循對象的比較規(guī)則

關(guān)于[-128,127]:

Integer類在初始化時(shí),一個(gè)靜態(tài)代碼塊將[-128,127]的每個(gè)整數(shù)都創(chuàng)建了Integer對象,并保存在一個(gè)數(shù)組中,今后在將[-128,127]中的一個(gè)整數(shù)自動裝箱成Integer對象時(shí),則直接指向這個(gè)數(shù)組中對應(yīng)的對象,因此可以用"=="比較它們的值是否相等

示例:包裝類與包裝類的比較

public class Test{  
    public static void main(String[] args) {  
        System.out.println(new Integer(2)==new Integer(2));
        System.out.println(new Integer(2).equals(new Integer(2)));
        
        Integer i1=127;
        Integer i2=127;
        System.out.println("127: i1==i2?  "+(i1==i2));
        Integer i3=128;
        Integer i4=128;
        System.out.println("128: i3==i4?  "+(i3==i4));
        
        Integer i5=new Integer(127);
        System.out.println("127: i1==i5?  "+(i1==i5));
        Integer i6=new Integer(128);
        System.out.println("128: i3==i6?  "+(i3==i6));
    }
}

輸出如下:

false
true
127: i1==i2? true
128: i3==i4? false
127: i1==i5? false
128: i3==i6? false

包裝類的compare()方法:compare(a,b)

a>b:返回1

a==b:返回0

a<b:返回-1

示例代碼:

public class Test{  
    public static void main(String[] args) {  
        System.out.println(Boolean.compare(true,false));
        System.out.println(Boolean.compare(new Boolean(false),true));
        System.out.println(Integer.compare(5,13));
        System.out.println(Integer.compare(new Integer(19),new Integer(10)));
    }
}

toString()方法

Object類的toString()方法返回的是類名@十六進(jìn)制hashCode()值

自己定義一個(gè)類的時(shí)候,一般都得重寫toString()方法,用以下格式:類名[主要變量1=值1,主要變量2=值2,...]

對象與對象的相等比較equals()與"=="

"==":

對引用變量而言,只有兩個(gè)變量指向同一個(gè)對象時(shí),才返回true

兩個(gè)對象如果沒有繼承關(guān)系,那么不能用"=="比較,會出現(xiàn)編譯錯(cuò)誤

equals():

自反性:對任意x,x.equals(x)一定返回true

對稱性:對任意x、y,如果x.equals(y)返回true,那么y.equals(x)也要返回true

傳遞性:對任意x、y、z,x.equals(y)返回true,y.equals(z)也返回true,那么x.equals(z)一定也返回true

一致性:只要兩個(gè)對象用于比較的信息沒有發(fā)生改變,那么不論調(diào)用equals()多少次,返回的結(jié)構(gòu)都應(yīng)該相同

對任意不是null的x,x.equals(null)一定返回false

Object的equals()方法跟"=="一樣,指向同一個(gè)對象才返回true

equals()一般都要重寫,重寫應(yīng)滿足的條件:

equals()重寫示例,固定寫法

class Person{    private String name;    private String id;    Person(){}    Person(String name,String id){        this.name=name;        this.id=id;
    }    public boolean equals(Object obj){        if (this==obj){   //如果二者指向同一個(gè)對象,返回true
            return true;
        }        if (obj!=null && obj.getClass()==Person.class){ //obj不為null,且指向的對象是Person類
            Person perObj=(Person)obj;          //類型轉(zhuǎn)換
            if(this.id.equals(perObj.id)){      //根據(jù)id是否相等判斷兩個(gè)Person對象是否相等
                return true;
            }
        }        return false; //如果obj為null或者obj指向的對象不是Person,返回false
    }
}

字符串與"=="

字符串有兩種情況,一種是字符串直接量,存儲在常量池中,常量池也在堆內(nèi)存中;一種是堆內(nèi)存中的字符串對象,存儲在堆內(nèi)存中

String的這個(gè)問題很復(fù)雜,慢慢來看,下面參考:http://www.cnblogs.com/kkgreen/archive/2011/08/24/2151450.html

代碼1:

String s1="AB";
String s2="A"+"B";
System.out.println(s1==s2);  //true。編譯階段即可確定s2="AB",運(yùn)行時(shí),s1和s2都指向常量池的"AB"

代碼2:

String s1="AB";
String s2="B";
String s3="A"+s2;
System.out.println(s1==s3);  //false。s2是變量,編譯階段不能確定s3的值

代碼3:

String s1="AB";final String s2="B";  //注意多了個(gè)finalString s3="A"+s2;
System.out.println(s1==s3); //true。s2的值不可變,編譯階段就確定了s3的值是"AB"

代碼4:

public static void main(String[] args) {  
        String s1="AB";        final String s2=getString();  //注意有final
        String s3="A"+s2;
        System.out.println(s1==s3);   //false。雖然s2值不可變,但是是通過方法返回的,編譯階段也不能確定其值
    }    static String getString(){        return "B";
    }

代碼5:

String s1="AB";
String s2="A";
String s3="B";
String s4=s2+s3;
System.out.println(s1==s4); //false.

代碼:6

String s1="AB";final String s2="A";final String s3="B";
String s4=s2+s3;
System.out.println(s1==s4); //true.s4的值在編譯期即可確定

代碼7:開始引入intern()方法

String s1="A";
String s2="B";
String s3=s1+s2;                     //s3實(shí)際指向堆內(nèi)存中的"AB"
System.out.println(s3==s3.intern()); //true。s3.intern()將堆內(nèi)存中"AB"對象的地址添加到常量池表中,而不是在常量池中再創(chuàng)建個(gè)對象,二者實(shí)際都指向堆內(nèi)存中的對象,因此二者相等
System.out.println(s3=="AB"); //true。s3指向堆內(nèi)存中"AB"的地址;"AB"按理說應(yīng)當(dāng)位于常量池,但常量池中只保存了"AB"在堆內(nèi)存中的地址,所有二者還是相當(dāng)
//intern()方法用于將該字符串追加到常量池中,如果已經(jīng)有了,就返回其引用;如果沒有就將地址添加到常量池表中,再返回其引用,實(shí)際指向的是堆內(nèi)存中的對象

代碼8:將代碼7最后兩行代碼換個(gè)順序

String s1="A";
String s2="B";
String s3=s1+s2;
System.out.println(s3=="AB");         //false.s3指向堆內(nèi)存中的對象,"AB"則在常量池中
System.out.println(s3==s3.intern());  //false.s3還是指向堆內(nèi)存中的對象,s3.intern()返回常量池中的"AB"的地址

總結(jié):

代碼7和8的結(jié)果十分詭異,以上所做的解釋也只是一種猜測,關(guān)鍵在于intern()方法,在常量池中沒有字符串的情況下,是新建個(gè)字符串對象,還是將字符串的地址添加在常量池表中

凡是編譯階段能確定的字符串,在運(yùn)行期就在常量池中創(chuàng)建一個(gè)運(yùn)算后的對象,而不會再計(jì)算一遍,這點(diǎn)存疑,從Java1.7開始,常量池位于堆內(nèi)存

用""創(chuàng)建的字符串位于常量池

用new String()構(gòu)造方法創(chuàng)建的字符串位于堆內(nèi)存中,運(yùn)行期創(chuàng)建

用"+"連接的字符串直接量,在編譯器就可以確定連接后的值,因此屬于常量池

用"+"連接的是字符串和變量或者方法返回值,則要到運(yùn)行期才能確定,屬于堆內(nèi)存對象

其他:

String s1=new String("ABC");String s2=new String("ABC");這兩個(gè)語句創(chuàng)建了3個(gè)String對象


Release Notes

Popular Entries