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對象