好東西分享
基本類型,或者叫做內(nèi)置類型,是JAVA中不同于類的特殊類型。它們是我們編程中使用最頻繁的類型,因此面試題中也總少不了它們的身影,在這篇文章中我們將從面試中常考的幾個(gè)方面來(lái)回顧一下與基本類型相關(guān)的知識(shí)。
基本類型共有九種,它們分別都有相對(duì)應(yīng)的包裝類。關(guān)于它們的詳細(xì)信息請(qǐng)看下表:
[img]http://zangweiren.iteye.com/upload/picture/pic/18450/8071c6c2-7cfb-3783-829a-a6abb3ae55e5.jpg [/img]
對(duì)于基本類型void以及它的包裝類java.lang.Void,我們都無(wú)法直接進(jìn)行操作。基本類型可以分為三類,字符類型char,布爾類型boolean以及數(shù)值類型byte、short、int、long、float、double。數(shù)值類型又可以分為整數(shù)類型byte、short、int、long和浮點(diǎn)數(shù)類型float、double。JAVA中的數(shù)值類型不存在無(wú)符號(hào)的,它們的取值范圍是固定的,不會(huì)隨著機(jī)器硬件環(huán)境或者操作系統(tǒng)的改變而改變。對(duì)于數(shù)值類型的基本類型的取值范圍,我們無(wú)需強(qiáng)制去記憶,因?yàn)樗鼈兊闹刀家呀?jīng)以常量的形式定義在對(duì)應(yīng)的包裝類中了。請(qǐng)看下面的例子:
- public ? class ?PrimitiveTypeTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? //?byte ??
- ????????System.out.println( "基本類型:byte?二進(jìn)制位數(shù):" ?+?Byte.SIZE); ??
- ????????System.out.println( "包裝類:java.lang.Byte" ); ??
- ????????System.out.println( "最小值:Byte.MIN_VALUE=" ?+?Byte.MIN_VALUE); ??
- ????????System.out.println( "最大值:Byte.MAX_VALUE=" ?+?Byte.MAX_VALUE); ??
- ????????System.out.println(); ??
- ??
- ???????? //?short ??
- ????????System.out.println( "基本類型:short?二進(jìn)制位數(shù):" ?+?Short.SIZE); ??
- ????????System.out.println( "包裝類:java.lang.Short" ); ??
- ????????System.out.println( "最小值:Short.MIN_VALUE=" ?+?Short.MIN_VALUE); ??
- ????????System.out.println( "最大值:Short.MAX_VALUE=" ?+?Short.MAX_VALUE); ??
- ????????System.out.println(); ??
- ??
- ???????? //?int ??
- ????????System.out.println( "基本類型:int?二進(jìn)制位數(shù):" ?+?Integer.SIZE); ??
- ????????System.out.println( "包裝類:java.lang.Integer" ); ??
- ????????System.out.println( "最小值:Integer.MIN_VALUE=" ?+?Integer.MIN_VALUE); ??
- ????????System.out.println( "最大值:Integer.MAX_VALUE=" ?+?Integer.MAX_VALUE); ??
- ????????System.out.println(); ??
- ??
- ???????? //?long ??
- ????????System.out.println( "基本類型:long?二進(jìn)制位數(shù):" ?+?Long.SIZE); ??
- ????????System.out.println( "包裝類:java.lang.Long" ); ??
- ????????System.out.println( "最小值:Long.MIN_VALUE=" ?+?Long.MIN_VALUE); ??
- ????????System.out.println( "最大值:Long.MAX_VALUE=" ?+?Long.MAX_VALUE); ??
- ????????System.out.println(); ??
- ??
- ???????? //?float ??
- ????????System.out.println( "基本類型:float?二進(jìn)制位數(shù):" ?+?Float.SIZE); ??
- ????????System.out.println( "包裝類:java.lang.Float" ); ??
- ????????System.out.println( "最小值:Float.MIN_VALUE=" ?+?Float.MIN_VALUE); ??
- ????????System.out.println( "最大值:Float.MAX_VALUE=" ?+?Float.MAX_VALUE); ??
- ????????System.out.println(); ??
- ??
- ???????? //?double ??
- ????????System.out.println( "基本類型:double?二進(jìn)制位數(shù):" ?+?Double.SIZE); ??
- ????????System.out.println( "包裝類:java.lang.Double" ); ??
- ????????System.out.println( "最小值:Double.MIN_VALUE=" ?+?Double.MIN_VALUE); ??
- ????????System.out.println( "最大值:Double.MAX_VALUE=" ?+?Double.MAX_VALUE); ??
- ????????System.out.println(); ??
- ??
- ???????? //?char ??
- ????????System.out.println( "基本類型:char?二進(jìn)制位數(shù):" ?+?Character.SIZE); ??
- ????????System.out.println( "包裝類:java.lang.Character" ); ??
- ???????? //?以數(shù)值形式而不是字符形式將Character.MIN_VALUE輸出到控制臺(tái) ??
- ????????System.out.println( "最小值:Character.MIN_VALUE=" ??
- ????????????????+?( int )?Character.MIN_VALUE); ??
- ???????? //?以數(shù)值形式而不是字符形式將Character.MAX_VALUE輸出到控制臺(tái) ??
- ????????System.out.println( "最大值:Character.MAX_VALUE=" ??
- ????????????????+?( int )?Character.MAX_VALUE); ??
- ????} ??
- }??
public class PrimitiveTypeTest { public static void main(String[] args) { // byte System.out.println("基本類型:byte 二進(jìn)制位數(shù):" + Byte.SIZE); System.out.println("包裝類:java.lang.Byte"); System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE); System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE); System.out.println(); // short System.out.println("基本類型:short 二進(jìn)制位數(shù):" + Short.SIZE); System.out.println("包裝類:java.lang.Short"); System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE); System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE); System.out.println(); // int System.out.println("基本類型:int 二進(jìn)制位數(shù):" + Integer.SIZE); System.out.println("包裝類:java.lang.Integer"); System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE); System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE); System.out.println(); // long System.out.println("基本類型:long 二進(jìn)制位數(shù):" + Long.SIZE); System.out.println("包裝類:java.lang.Long"); System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE); System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE); System.out.println(); // float System.out.println("基本類型:float 二進(jìn)制位數(shù):" + Float.SIZE); System.out.println("包裝類:java.lang.Float"); System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE); System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE); System.out.println(); // double System.out.println("基本類型:double 二進(jìn)制位數(shù):" + Double.SIZE); System.out.println("包裝類:java.lang.Double"); System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE); System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE); System.out.println(); // char System.out.println("基本類型:char 二進(jìn)制位數(shù):" + Character.SIZE); System.out.println("包裝類:java.lang.Character"); // 以數(shù)值形式而不是字符形式將Character.MIN_VALUE輸出到控制臺(tái) System.out.println("最小值:Character.MIN_VALUE=" + (int) Character.MIN_VALUE); // 以數(shù)值形式而不是字符形式將Character.MAX_VALUE輸出到控制臺(tái) System.out.println("最大值:Character.MAX_VALUE=" + (int) Character.MAX_VALUE); } }
運(yùn)行結(jié)果:
- 基本類型:byte 二進(jìn)制位數(shù):8
- 包裝類:java.lang.Byte
- 最小值:Byte.MIN_VALUE=-128
- 最大值:Byte.MAX_VALUE=127
- 基本類型:short 二進(jìn)制位數(shù):16
- 包裝類:java.lang.Short
- 最小值:Short.MIN_VALUE=-32768
- 最大值:Short.MAX_VALUE=32767
- 基本類型:int 二進(jìn)制位數(shù):32
- 包裝類:java.lang.Integer
- 最小值:Integer.MIN_VALUE=-2147483648
- 最大值:Integer.MAX_VALUE=2147483647
- 基本類型:long 二進(jìn)制位數(shù):64
- 包裝類:java.lang.Long
- 最小值:Long.MIN_VALUE=-9223372036854775808
- 最大值:Long.MAX_VALUE=9223372036854775807
- 基本類型:float 二進(jìn)制位數(shù):32
- 包裝類:java.lang.Float
- 最小值:Float.MIN_VALUE=1.4E-45
- 最大值:Float.MAX_VALUE=3.4028235E38
- 基本類型:double 二進(jìn)制位數(shù):64
- 包裝類:java.lang.Double
- 最小值:Double.MIN_VALUE=4.9E-324
- 最大值:Double.MAX_VALUE=1.7976931348623157E308
- 基本類型:char 二進(jìn)制位數(shù):16
- 包裝類:java.lang.Character
- 最小值:Character.MIN_VALUE=0
- 最大值:Character.MAX_VALUE=65535
Float和Double的最小值和最大值都是以科學(xué)記數(shù)法的形式輸出的,結(jié)尾的“E+數(shù)字”表示E之前的數(shù)字要乘以10的多少倍。比如3.14E3就是3.14×1000=3140,3.14E-3就是3.14/1000=0.00314。
大家將運(yùn)行結(jié)果與上表信息仔細(xì)比較就會(huì)發(fā)現(xiàn)float、double兩種類型的最小值與Float.MIN_VALUE、Double.MIN_VALUE的值并不相同,這是為什么呢?實(shí)際上Float.MIN_VALUE和Double.MIN_VALUE分別指的是float和double類型所能表示的最小正數(shù)。也就是說(shuō)存在這樣一種情況,0到±Float.MIN_VALUE之間的值float類型無(wú)法表示,0到±Double.MIN_VALUE之間的值double類型無(wú)法表示。這并沒有什么好奇怪的,因?yàn)檫@些范圍內(nèi)的數(shù)值超出了它們的精度范圍。
基本類型存儲(chǔ)在棧中,因此它們的存取速度要快于存儲(chǔ)在堆中的對(duì)應(yīng)包裝類的實(shí)例對(duì)象。從Java5.0(1.5)開始,JAVA虛擬機(jī)(Java Virtual Machine)可以完成基本類型和它們對(duì)應(yīng)包裝類之間的自動(dòng)轉(zhuǎn)換。因此我們?cè)谫x值、參數(shù)傳遞以及數(shù)學(xué)運(yùn)算的時(shí)候像使用基本類型一樣使用它們的包裝類,但這并不意味著你可以通過(guò)基本類型調(diào)用它們的包裝類才具有的方法。另外,所有基本類型(包括void)的包裝類都使用了final修飾,因此我們無(wú)法繼承它們擴(kuò)展新的類,也無(wú)法重寫它們的任何方法。
各種數(shù)值類型之間的賦值與轉(zhuǎn)換遵循什么規(guī)律呢?我們來(lái)看下面這個(gè)例子:
- public ? class ?PrimitiveTypeTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? //?給byte類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
- ???????? byte ?byte_a?=? 1 ; ??
- ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
- ???????? //?byte?byte_b?=?1000; ??
- ???????? //?把一個(gè)long型值賦值給byte型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出byte類型的取值范圍 ??
- ???????? //?byte?byte_c?=?1L; ??
- ??
- ???????? //?給short類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
- ???????? short ?short_a?=? 1 ; ??
- ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
- ???????? //?short?short_b?=?70000; ??
- ???????? //?把一個(gè)long型值賦值給short型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出short類型的取值范圍 ??
- ???????? //?byte?short_c?=?1L; ??
- ??
- ???????? //?給short類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
- ???????? int ?int_a?=? 1 ; ??
- ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
- ???????? //?int?int_b?=?2200000000; ??
- ???????? //?把一個(gè)long型值賦值給int型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出int類型的取值范圍 ??
- ???????? //?int?int_c?=?1L; ??
- ??
- ???????? //?可以把一個(gè)int型值直接賦值給long型變量,數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
- ???????? long ?long_a?=? 1 ; ??
- ???????? //?如果給long型變量賦予的值超出了int型值的范圍,數(shù)字后必須加L(不區(qū)分大小寫)標(biāo)識(shí) ??
- ???????? long ?long_b?=?2200000000L; ??
- ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
- ???????? //?long?long_c?=?9300000000000000000L; ??
- ??
- ???????? //?可以把一個(gè)int型值直接賦值給float型變量 ??
- ???????? float ?float_a?=? 1 ; ??
- ???????? //?可以把一個(gè)long型值直接賦值給float型變量 ??
- ???????? float ?float_b?=?1L; ??
- ???????? //?沒有F(不區(qū)分大小寫)后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double型的,不能將它直接賦值給float型變量 ??
- ???????? //?float?float_c?=?1.0; ??
- ???????? //?float型數(shù)值需要有一個(gè)F(不區(qū)分大小寫)后綴標(biāo)識(shí) ??
- ???????? float ?float_d?=? 1 .0F; ??
- ???????? //?把一個(gè)double型值賦值給float型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出float類型的取值范圍 ??
- ???????? //?float?float_e?=?1.0D; ??
- ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
- ???????? //?float?float_f?=?3.5000000E38F; ??
- ??
- ???????? //?可以把一個(gè)int型值直接賦值給double型變量 ??
- ???????? double ?double_a?=? 1 ; ??
- ???????? //?可以把一個(gè)long型值直接賦值給double型變量 ??
- ???????? double ?double_b?=?1L; ??
- ???????? //?可以把一個(gè)float型值直接賦值給double型變量 ??
- ???????? double ?double_c?=?1F; ??
- ???????? //?不帶后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double類型的,可以直接賦值 ??
- ???????? double ?double_d?=? 1.0 ; ??
- ???????? //?也可以給數(shù)字增加一個(gè)D(不區(qū)分大小寫)后綴標(biāo)識(shí),明確標(biāo)出它是double類型的 ??
- ???????? double ?double_e?=? 1 .0D; ??
- ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
- ???????? //?double?double_f?=?1.8000000000000000E308D; ??
- ??
- ???????? //?把一個(gè)double型值賦值給一個(gè)byte類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出byte類型的取值范圍 ??
- ???????? //?byte?byte_d?=?1.0D; ??
- ???????? //?把一個(gè)double型值賦值給一個(gè)short類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出short類型的取值范圍 ??
- ???????? //?short?short_d?=?1.0D; ??
- ???????? //?把一個(gè)double型值賦值給一個(gè)int類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出int類型的取值范圍 ??
- ???????? //?int?int_d?=?1.0D; ??
- ???????? //?把一個(gè)double型值賦值給一個(gè)long類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出long類型的取值范圍 ??
- ???????? //?long?long_d?=?1.0D; ??
- ??
- ???????? //?可以用字符初始化一個(gè)char型變量 ??
- ???????? char ?char_a?=? 'a' ; ??
- ???????? //?也可以用一個(gè)int型數(shù)值初始化char型變量 ??
- ???????? char ?char_b?=? 1 ; ??
- ???????? //?把一個(gè)long型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 ??
- ???????? //?char?char_c?=?1L; ??
- ???????? //?把一個(gè)float型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 ??
- ???????? //?char?char_d?=?1.0F; ??
- ???????? //?把一個(gè)double型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 ??
- ???????? //?char?char_e?=?1.0D; ??
- ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
- ???????? //?char?char_f?=?70000; ??
- ????} ??
- }??
public class PrimitiveTypeTest { public static void main(String[] args) { // 給byte類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) byte byte_a = 1; // 編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) // byte byte_b = 1000; // 把一個(gè)long型值賦值給byte型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出byte類型的取值范圍 // byte byte_c = 1L; // 給short類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) short short_a = 1; // 編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) // short short_b = 70000; // 把一個(gè)long型值賦值給short型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出short類型的取值范圍 // byte short_c = 1L; // 給short類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) int int_a = 1; // 編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) // int int_b = 2200000000; // 把一個(gè)long型值賦值給int型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出int類型的取值范圍 // int int_c = 1L; // 可以把一個(gè)int型值直接賦值給long型變量,數(shù)字后無(wú)需后綴標(biāo)識(shí) long long_a = 1; // 如果給long型變量賦予的值超出了int型值的范圍,數(shù)字后必須加L(不區(qū)分大小寫)標(biāo)識(shí) long long_b = 2200000000L; // 編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) // long long_c = 9300000000000000000L; // 可以把一個(gè)int型值直接賦值給float型變量 float float_a = 1; // 可以把一個(gè)long型值直接賦值給float型變量 float float_b = 1L; // 沒有F(不區(qū)分大小寫)后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double型的,不能將它直接賦值給float型變量 // float float_c = 1.0; // float型數(shù)值需要有一個(gè)F(不區(qū)分大小寫)后綴標(biāo)識(shí) float float_d = 1.0F; // 把一個(gè)double型值賦值給float型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出float類型的取值范圍 // float float_e = 1.0D; // 編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) // float float_f = 3.5000000E38F; // 可以把一個(gè)int型值直接賦值給double型變量 double double_a = 1; // 可以把一個(gè)long型值直接賦值給double型變量 double double_b = 1L; // 可以把一個(gè)float型值直接賦值給double型變量 double double_c = 1F; // 不帶后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double類型的,可以直接賦值 double double_d = 1.0; // 也可以給數(shù)字增加一個(gè)D(不區(qū)分大小寫)后綴標(biāo)識(shí),明確標(biāo)出它是double類型的 double double_e = 1.0D; // 編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) // double double_f = 1.8000000000000000E308D; // 把一個(gè)double型值賦值給一個(gè)byte類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出byte類型的取值范圍 // byte byte_d = 1.0D; // 把一個(gè)double型值賦值給一個(gè)short類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出short類型的取值范圍 // short short_d = 1.0D; // 把一個(gè)double型值賦值給一個(gè)int類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出int類型的取值范圍 // int int_d = 1.0D; // 把一個(gè)double型值賦值給一個(gè)long類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出long類型的取值范圍 // long long_d = 1.0D; // 可以用字符初始化一個(gè)char型變量 char char_a = 'a'; // 也可以用一個(gè)int型數(shù)值初始化char型變量 char char_b = 1; // 把一個(gè)long型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 // char char_c = 1L; // 把一個(gè)float型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 // char char_d = 1.0F; // 把一個(gè)double型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 // char char_e = 1.0D; // 編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) // char char_f = 70000; } }
從上面的例子中我們可以得出如下幾條結(jié)論:
- 未帶有字符后綴標(biāo)識(shí)的整數(shù)默認(rèn)為int類型;未帶有字符后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double類型。
- 如果一個(gè)整數(shù)的值超出了int類型能夠表示的范圍,則必須增加后綴“L”(不區(qū)分大小寫,建議用大寫,因?yàn)樾懙腖與阿拉伯?dāng)?shù)字1很容易混淆),表示為long型。
- 帶有“F”(不區(qū)分大小寫)后綴的整數(shù)和浮點(diǎn)數(shù)都是float類型的;帶有“D”(不區(qū)分大小寫)后綴的整數(shù)和浮點(diǎn)數(shù)都是double類型的。
- 編譯器會(huì)在編譯期對(duì)byte、short、int、long、float、double、char型變量的值進(jìn)行檢查,如果超出了它們的取值范圍就會(huì)報(bào)錯(cuò)。
- int型值可以賦給所有數(shù)值類型的變量;long型值可以賦給long、float、double類型的變量;float型值可以賦給float、double類型的變量;double型值只能賦給double類型變量。
下圖顯示了幾種基本類型之間的默認(rèn)邏輯轉(zhuǎn)換關(guān)系:
圖中的實(shí)線表示無(wú)精度損失的轉(zhuǎn)換,而虛線則表示這樣的轉(zhuǎn)換可能會(huì)損失一定的精度。如果我們想把一個(gè)能表示更大范圍或者更高精度的類型,轉(zhuǎn)換為一個(gè)范圍更小或者精度更低的類型時(shí),就需要使用強(qiáng)制類型轉(zhuǎn)換(Cast)了。不過(guò)我們要盡量避免這種用法,因?yàn)樗3Rl(fā)錯(cuò)誤。請(qǐng)看下面的例子,如果不運(yùn)行代碼,你能預(yù)測(cè)它的結(jié)果嗎?
- public ? class ?PrimitiveTypeTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? int ?a?=? 123456 ; ??
- ???????? short ?b?=?( short )?a; ??
- ???????? //?b的值會(huì)是什么呢? ??
- ????????System.out.println(b); ??
- ????} ??
- }??
public class PrimitiveTypeTest { public static void main(String[] args) { int a = 123456; short b = (short) a; // b的值會(huì)是什么呢? System.out.println(b); } }
運(yùn)行結(jié)果:
- -7616
運(yùn)算符對(duì)基本類型的影響
當(dāng)使用+、-、*、/、%運(yùn)算符對(duì)基本類型進(jìn)行運(yùn)算時(shí),遵循如下規(guī)則:
- 只要兩個(gè)操作數(shù)中有一個(gè)是double類型的,另一個(gè)將會(huì)被轉(zhuǎn)換成double類型,并且結(jié)果也是double類型;
- 否則,只要兩個(gè)操作數(shù)中有一個(gè)是float類型的,另一個(gè)將會(huì)被轉(zhuǎn)換成float類型,并且結(jié)果也是float類型;
- 否則,只要兩個(gè)操作數(shù)中有一個(gè)是long類型的,另一個(gè)將會(huì)被轉(zhuǎn)換成long類型,并且結(jié)果也是long類型;
- 否則,兩個(gè)操作數(shù)(包括byte、short、int、char)都將會(huì)被轉(zhuǎn)換成int類型,并且結(jié)果也是int類型。
當(dāng)使用+=、-=、*=、/=、%=、運(yùn)算符對(duì)基本類型進(jìn)行運(yùn)算時(shí),遵循如下規(guī)則:
- 運(yùn)算符右邊的數(shù)值將首先被強(qiáng)制轉(zhuǎn)換成與運(yùn)算符左邊數(shù)值相同的類型,然后再執(zhí)行運(yùn)算,且運(yùn)算結(jié)果與運(yùn)算符左邊數(shù)值類型相同。
了解了這些,我們就能解答下面這個(gè)常考的面試題了。請(qǐng)看:
乍一看,覺得它們都應(yīng)該沒有錯(cuò)誤,可以正常運(yùn)行。我們來(lái)寫個(gè)例子試試:
- public ? class ?PrimitiveTypeTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? short ?s1?=? 1 ; ??
- ???????? //?這一行代碼會(huì)報(bào)編譯錯(cuò)誤 ??
- ???????? //?s1?=?s1?+?1; ??
- ???????? //?這一行代碼沒有報(bào)錯(cuò) ??
- ????????s1?=? 1 ?+? 1 ; ??
- ???????? //?這一行代碼也沒有報(bào)錯(cuò) ??
- ????????s1?+=? 1 ; ??
- ????} ??
- }??
public class PrimitiveTypeTest { public static void main(String[] args) { short s1 = 1; // 這一行代碼會(huì)報(bào)編譯錯(cuò)誤 // s1 = s1 + 1; // 這一行代碼沒有報(bào)錯(cuò) s1 = 1 + 1; // 這一行代碼也沒有報(bào)錯(cuò) s1 += 1; } }
從例子中我們可以看出結(jié)果了。利用上面列舉的規(guī)律,也很容易解釋。在s1=s1+1;中,s1+1運(yùn)算的結(jié)果是int型,把它賦值給一個(gè)short型變量s1,所以會(huì)報(bào)錯(cuò);而在s1+=1;中,由于是s1是short類型的,所以1首先被強(qiáng)制轉(zhuǎn)換為short型,然后再參與運(yùn)算,并且結(jié)果也是short類型的,因此不會(huì)報(bào)錯(cuò)。那么,s1=1+1;為什么不報(bào)錯(cuò)呢?這是因?yàn)?+1是個(gè)編譯時(shí)可以確定的常量,“+”運(yùn)算在編譯時(shí)就被執(zhí)行了,而不是在程序執(zhí)行的時(shí)候,這個(gè)語(yǔ)句的效果等同于s1=2,所以不會(huì)報(bào)錯(cuò)。前面講過(guò)了,對(duì)基本類型執(zhí)行強(qiáng)制類型轉(zhuǎn)換可能得出錯(cuò)誤的結(jié)果,因此在使用+=、-=、*=、/=、%=等運(yùn)算符時(shí),要多加注意。
當(dāng)使用“==”運(yùn)算符在基本類型和其包裝類對(duì)象之間比較時(shí),遵循如下規(guī)則:
- 只要兩個(gè)操作數(shù)中有一個(gè)是基本類型,就是比較它們的數(shù)值是否相等。
- 否則,就是判斷這兩個(gè)對(duì)象的內(nèi)存地址是否相等,即是否是同一個(gè)對(duì)象。
下面的測(cè)試?yán)觿t驗(yàn)證了以上的規(guī)則:
- public ? class ?EqualsTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? //?int類型用int類型初始化 ??
- ???????? int ?int_int?=? 0 ; ??
- ???????? //?int類型用Integer類型初始化 ??
- ???????? int ?int_Integer?=? new ?Integer( 0 ); ??
- ???????? //?Integer類型用Integer類型初始化 ??
- ????????Integer?Integer_Integer?=? new ?Integer( 0 ); ??
- ???????? //?Integer類型用int類型初始化 ??
- ????????Integer?Integer_int?=? 0 ; ??
- ??
- ????????System.out.println( "int_int?==?int_Integer結(jié)果是:" ??
- ????????????????+?(int_int?==?int_Integer)); ??
- ????????System.out.println( "Integer_Integer?==?Integer_int結(jié)果是:" ??
- ????????????????+?(Integer_Integer?==?Integer_int)); ??
- ????????System.out.println(); ??
- ????????System.out.println( "int_int?==?Integer_Integer結(jié)果是:" ??
- ????????????????+?(int_int?==?Integer_Integer)); ??
- ????????System.out.println( "Integer_Integer?==?int_int結(jié)果是:" ??
- ????????????????+?(Integer_Integer?==?int_int)); ??
- ????????System.out.println(); ??
- ??
- ???????? //?boolean類型用boolean類型初始化 ??
- ???????? boolean ?boolean_boolean?=? true ; ??
- ???????? //?boolean類型用Boolean類型初始化 ??
- ???????? boolean ?boolean_Boolean?=? new ?Boolean( true ); ??
- ???????? //?Boolean類型用Boolean類型初始化 ??
- ????????Boolean?Boolean_Boolean?=? new ?Boolean( true ); ??
- ???????? //?Boolean類型用boolean類型初始化 ??
- ????????Boolean?Boolean_boolean?=? true ; ??
- ??
- ????????System.out.println( "boolean_boolean?==?boolean_Boolean結(jié)果是:" ??
- ????????????????+?(boolean_boolean?==?boolean_Boolean)); ??
- ????????System.out.println( "Boolean_Boolean?==?Boolean_boolean結(jié)果是:" ??
- ????????????????+?(Boolean_Boolean?==?Boolean_boolean)); ??
- ????????System.out.println(); ??
- ????????System.out.println( "boolean_boolean?==?Boolean_Boolean結(jié)果是:" ??
- ????????????????+?(boolean_boolean?==?Boolean_Boolean)); ??
- ????????System.out.println( "Boolean_Boolean?==?boolean_boolean結(jié)果是:" ??
- ????????????????+?(Boolean_Boolean?==?boolean_boolean)); ??
- ????} ??
- }??
public class EqualsTest { public static void main(String[] args) { // int類型用int類型初始化 int int_int = 0; // int類型用Integer類型初始化 int int_Integer = new Integer(0); // Integer類型用Integer類型初始化 Integer Integer_Integer = new Integer(0); // Integer類型用int類型初始化 Integer Integer_int = 0; System.out.println("int_int == int_Integer結(jié)果是:" + (int_int == int_Integer)); System.out.println("Integer_Integer == Integer_int結(jié)果是:" + (Integer_Integer == Integer_int)); System.out.println(); System.out.println("int_int == Integer_Integer結(jié)果是:" + (int_int == Integer_Integer)); System.out.println("Integer_Integer == int_int結(jié)果是:" + (Integer_Integer == int_int)); System.out.println(); // boolean類型用boolean類型初始化 boolean boolean_boolean = true; // boolean類型用Boolean類型初始化 boolean boolean_Boolean = new Boolean(true); // Boolean類型用Boolean類型初始化 Boolean Boolean_Boolean = new Boolean(true); // Boolean類型用boolean類型初始化 Boolean Boolean_boolean = true; System.out.println("boolean_boolean == boolean_Boolean結(jié)果是:" + (boolean_boolean == boolean_Boolean)); System.out.println("Boolean_Boolean == Boolean_boolean結(jié)果是:" + (Boolean_Boolean == Boolean_boolean)); System.out.println(); System.out.println("boolean_boolean == Boolean_Boolean結(jié)果是:" + (boolean_boolean == Boolean_Boolean)); System.out.println("Boolean_Boolean == boolean_boolean結(jié)果是:" + (Boolean_Boolean == boolean_boolean)); } }
運(yùn)行結(jié)果:
- int_int == int_Integer結(jié)果是:true
- Integer_Integer == Integer_int結(jié)果是:false
- int_int == Integer_Integer結(jié)果是:true
- Integer_Integer == int_int結(jié)果是:true
- boolean_boolean == boolean_Boolean結(jié)果是:true
- Boolean_Boolean == Boolean_boolean結(jié)果是:false
- boolean_boolean == Boolean_Boolean結(jié)果是:true
- Boolean_Boolean == boolean_boolean結(jié)果是:true
為了便于查看,上例中變量命名沒有采用規(guī)范的方式,而是采用了“變量類型”+“_”+“初始化值類型”的方式。
Math.round()方法
java.lang.Math類里有兩個(gè)round()方法,它們的定義如下:
- public ? static ? int ?round( float ?a)?{ ??
- ???? //other?code ??
- } ??
- ??
- public ? static ? long ?round( double ?a)?{ ??
- ???? //other?code ??
- }??
public static int round(float a) { //other code } public static long round(double a) { //other code }
它們的返回值都是整數(shù),且都采用四舍五入法。運(yùn)算規(guī)則如下:
- 如果參數(shù)為正數(shù),且小數(shù)點(diǎn)后第一位>=5,運(yùn)算結(jié)果為參數(shù)的整數(shù)部分+1。
- 如果參數(shù)為負(fù)數(shù),且小數(shù)點(diǎn)后第一位>5,運(yùn)算結(jié)果為參數(shù)的整數(shù)部分-1。
- 如果參數(shù)為正數(shù),且小數(shù)點(diǎn)后第一位<5;或者參數(shù)為負(fù)數(shù),且小數(shù)點(diǎn)后第一位<=5,運(yùn)算結(jié)果為參數(shù)的整數(shù)部分。
我們可以通過(guò)下面的例子來(lái)驗(yàn)證:
- public ? class ?MathTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ????????System.out.println( "小數(shù)點(diǎn)后第一位=5" ); ??
- ????????System.out.println( "正數(shù):Math.round(11.5)=" ?+?Math.round( 11.5 )); ??
- ????????System.out.println( "負(fù)數(shù):Math.round(-11.5)=" ?+?Math.round(- 11.5 )); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "小數(shù)點(diǎn)后第一位<5" ); ??
- ????????System.out.println( "正數(shù):Math.round(11.46)=" ?+?Math.round( 11.46 )); ??
- ????????System.out.println( "負(fù)數(shù):Math.round(-11.46)=" ?+?Math.round(- 11.46 )); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "小數(shù)點(diǎn)后第一位>5" ); ??
- ????????System.out.println( "正數(shù):Math.round(11.68)=" ?+?Math.round( 11.68 )); ??
- ????????System.out.println( "負(fù)數(shù):Math.round(-11.68)=" ?+?Math.round(- 11.68 )); ??
- ????} ??
- }??
public class MathTest { public static void main(String[] args) { System.out.println("小數(shù)點(diǎn)后第一位=5"); System.out.println("正數(shù):Math.round(11.5)=" + Math.round(11.5)); System.out.println("負(fù)數(shù):Math.round(-11.5)=" + Math.round(-11.5)); System.out.println(); System.out.println("小數(shù)點(diǎn)后第一位<5"); System.out.println("正數(shù):Math.round(11.46)=" + Math.round(11.46)); System.out.println("負(fù)數(shù):Math.round(-11.46)=" + Math.round(-11.46)); System.out.println(); System.out.println("小數(shù)點(diǎn)后第一位>5"); System.out.println("正數(shù):Math.round(11.68)=" + Math.round(11.68)); System.out.println("負(fù)數(shù):Math.round(-11.68)=" + Math.round(-11.68)); } }
運(yùn)行結(jié)果:
- 小數(shù)點(diǎn)后第一位=5
- 正數(shù):Math.round(11.5)=12
- 負(fù)數(shù):Math.round(-11.5)=-11
- 小數(shù)點(diǎn)后第一位<5
- 正數(shù):Math.round(11.46)=11
- 負(fù)數(shù):Math.round(-11.46)=-11
- 小數(shù)點(diǎn)后第一位>5
- 正數(shù):Math.round(11.68)=12
- 負(fù)數(shù):Math.round(-11.68)=-12
根據(jù)上面例子的運(yùn)行結(jié)果,我們還可以按照如下方式總結(jié),或許更加容易記憶:
- 參數(shù)的小數(shù)點(diǎn)后第一位<5,運(yùn)算結(jié)果為參數(shù)整數(shù)部分。
- 參數(shù)的小數(shù)點(diǎn)后第一位>5,運(yùn)算結(jié)果為參數(shù)整數(shù)部分絕對(duì)值+1,符號(hào)(即正負(fù))不變。
- 參數(shù)的小數(shù)點(diǎn)后第一位=5,正數(shù)運(yùn)算結(jié)果為整數(shù)部分+1,負(fù)數(shù)運(yùn)算結(jié)果為整數(shù)部分。
但是上面的結(jié)論仍然不是很好記憶。我們來(lái)看看round()方法的內(nèi)部實(shí)現(xiàn)會(huì)給我們帶來(lái)什么啟發(fā)?我們來(lái)看這兩個(gè)方法內(nèi)部的代碼:
- public ? static ? int ?round( float ?a)?{ ??
- ???? return ?( int )floor(a?+? 0 .5f); ??
- } ??
- ??
- public ? static ? long ?round( double ?a)?{ ??
- ???? return ?( long )floor(a?+? 0 .5d); ??
- }??
public static int round(float a) { return (int)floor(a + 0.5f); } public static long round(double a) { return (long)floor(a + 0.5d); }
看來(lái)它們都是將參數(shù)值+0.5后交與floor()進(jìn)行運(yùn)算,然后取返回值。那么floor()方法的作用又是什么呢?它是取一個(gè)小于等于參數(shù)值的最大整數(shù)。比如經(jīng)過(guò)floor()方法運(yùn)算后,如果參數(shù)是10.2則返回10,13返回13,-20.82返回-21,-16返回-16等等。既然是這樣,我們就可以用一句話來(lái)概括round()方法的運(yùn)算效果了:
- Math類的round()方法的運(yùn)算結(jié)果是一個(gè)<=(參數(shù)值+0.5)的最大整數(shù)。
switch語(yǔ)句
哪些類型可以用于switch語(yǔ)句的判斷呢?我們做個(gè)測(cè)試就知道了:
- public ? class ?MathTest?{ ??
- ???? //?枚舉類型,Java5.0以上版本可用 ??
- ???? static ? enum ?enum_e?{ ??
- ????????A,?B ??
- ????} ??
- ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? //?byte ??
- ???????? byte ?byte_n?=? 0 ; ??
- ???????? switch ?(byte_n)?{ ??
- ???????? case ? 0 : ??
- ????????????System.out.println( "byte可以用于switch語(yǔ)句" ); ??
- ????????????</sp
- 2010-05-01 00:08
- 瀏覽 254
- 評(píng)論(0)
- 分類: 非技術(shù)
- 相關(guān)推薦
發(fā)表評(píng)論
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

評(píng)論