日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

JAVA面試題解惑系列(八)——聊聊基本類型(內(nèi)

系統(tǒng) 2203 0

好東西分享

基本類型,或者叫做內(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)看下面的例子:

Java代碼 復(fù)制代碼
  1. public ? class ?PrimitiveTypeTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? //?byte ??
  4. ????????System.out.println( "基本類型:byte?二進(jìn)制位數(shù):" ?+?Byte.SIZE); ??
  5. ????????System.out.println( "包裝類:java.lang.Byte" ); ??
  6. ????????System.out.println( "最小值:Byte.MIN_VALUE=" ?+?Byte.MIN_VALUE); ??
  7. ????????System.out.println( "最大值:Byte.MAX_VALUE=" ?+?Byte.MAX_VALUE); ??
  8. ????????System.out.println(); ??
  9. ??
  10. ???????? //?short ??
  11. ????????System.out.println( "基本類型:short?二進(jìn)制位數(shù):" ?+?Short.SIZE); ??
  12. ????????System.out.println( "包裝類:java.lang.Short" ); ??
  13. ????????System.out.println( "最小值:Short.MIN_VALUE=" ?+?Short.MIN_VALUE); ??
  14. ????????System.out.println( "最大值:Short.MAX_VALUE=" ?+?Short.MAX_VALUE); ??
  15. ????????System.out.println(); ??
  16. ??
  17. ???????? //?int ??
  18. ????????System.out.println( "基本類型:int?二進(jìn)制位數(shù):" ?+?Integer.SIZE); ??
  19. ????????System.out.println( "包裝類:java.lang.Integer" ); ??
  20. ????????System.out.println( "最小值:Integer.MIN_VALUE=" ?+?Integer.MIN_VALUE); ??
  21. ????????System.out.println( "最大值:Integer.MAX_VALUE=" ?+?Integer.MAX_VALUE); ??
  22. ????????System.out.println(); ??
  23. ??
  24. ???????? //?long ??
  25. ????????System.out.println( "基本類型:long?二進(jìn)制位數(shù):" ?+?Long.SIZE); ??
  26. ????????System.out.println( "包裝類:java.lang.Long" ); ??
  27. ????????System.out.println( "最小值:Long.MIN_VALUE=" ?+?Long.MIN_VALUE); ??
  28. ????????System.out.println( "最大值:Long.MAX_VALUE=" ?+?Long.MAX_VALUE); ??
  29. ????????System.out.println(); ??
  30. ??
  31. ???????? //?float ??
  32. ????????System.out.println( "基本類型:float?二進(jìn)制位數(shù):" ?+?Float.SIZE); ??
  33. ????????System.out.println( "包裝類:java.lang.Float" ); ??
  34. ????????System.out.println( "最小值:Float.MIN_VALUE=" ?+?Float.MIN_VALUE); ??
  35. ????????System.out.println( "最大值:Float.MAX_VALUE=" ?+?Float.MAX_VALUE); ??
  36. ????????System.out.println(); ??
  37. ??
  38. ???????? //?double ??
  39. ????????System.out.println( "基本類型:double?二進(jìn)制位數(shù):" ?+?Double.SIZE); ??
  40. ????????System.out.println( "包裝類:java.lang.Double" ); ??
  41. ????????System.out.println( "最小值:Double.MIN_VALUE=" ?+?Double.MIN_VALUE); ??
  42. ????????System.out.println( "最大值:Double.MAX_VALUE=" ?+?Double.MAX_VALUE); ??
  43. ????????System.out.println(); ??
  44. ??
  45. ???????? //?char ??
  46. ????????System.out.println( "基本類型:char?二進(jìn)制位數(shù):" ?+?Character.SIZE); ??
  47. ????????System.out.println( "包裝類:java.lang.Character" ); ??
  48. ???????? //?以數(shù)值形式而不是字符形式將Character.MIN_VALUE輸出到控制臺(tái) ??
  49. ????????System.out.println( "最小值:Character.MIN_VALUE=" ??
  50. ????????????????+?( int )?Character.MIN_VALUE); ??
  51. ???????? //?以數(shù)值形式而不是字符形式將Character.MAX_VALUE輸出到控制臺(tái) ??
  52. ????????System.out.println( "最大值:Character.MAX_VALUE=" ??
  53. ????????????????+?( int )?Character.MAX_VALUE); ??
  54. ????} ??
  55. }??
    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é)果:

  1. 基本類型:byte 二進(jìn)制位數(shù):8
  2. 包裝類:java.lang.Byte
  3. 最小值:Byte.MIN_VALUE=-128
  4. 最大值:Byte.MAX_VALUE=127
  5. 基本類型:short 二進(jìn)制位數(shù):16
  6. 包裝類:java.lang.Short
  7. 最小值:Short.MIN_VALUE=-32768
  8. 最大值:Short.MAX_VALUE=32767
  9. 基本類型:int 二進(jìn)制位數(shù):32
  10. 包裝類:java.lang.Integer
  11. 最小值:Integer.MIN_VALUE=-2147483648
  12. 最大值:Integer.MAX_VALUE=2147483647
  13. 基本類型:long 二進(jìn)制位數(shù):64
  14. 包裝類:java.lang.Long
  15. 最小值:Long.MIN_VALUE=-9223372036854775808
  16. 最大值:Long.MAX_VALUE=9223372036854775807
  17. 基本類型:float 二進(jìn)制位數(shù):32
  18. 包裝類:java.lang.Float
  19. 最小值:Float.MIN_VALUE=1.4E-45
  20. 最大值:Float.MAX_VALUE=3.4028235E38
  21. 基本類型:double 二進(jìn)制位數(shù):64
  22. 包裝類:java.lang.Double
  23. 最小值:Double.MIN_VALUE=4.9E-324
  24. 最大值:Double.MAX_VALUE=1.7976931348623157E308
  25. 基本類型:char 二進(jìn)制位數(shù):16
  26. 包裝類:java.lang.Character
  27. 最小值:Character.MIN_VALUE=0
  28. 最大值: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è)例子:

Java代碼 復(fù)制代碼
  1. public ? class ?PrimitiveTypeTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? //?給byte類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
  4. ???????? byte ?byte_a?=? 1 ; ??
  5. ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
  6. ???????? //?byte?byte_b?=?1000; ??
  7. ???????? //?把一個(gè)long型值賦值給byte型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出byte類型的取值范圍 ??
  8. ???????? //?byte?byte_c?=?1L; ??
  9. ??
  10. ???????? //?給short類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
  11. ???????? short ?short_a?=? 1 ; ??
  12. ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
  13. ???????? //?short?short_b?=?70000; ??
  14. ???????? //?把一個(gè)long型值賦值給short型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出short類型的取值范圍 ??
  15. ???????? //?byte?short_c?=?1L; ??
  16. ??
  17. ???????? //?給short類型變量賦值時(shí),數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
  18. ???????? int ?int_a?=? 1 ; ??
  19. ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
  20. ???????? //?int?int_b?=?2200000000; ??
  21. ???????? //?把一個(gè)long型值賦值給int型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出int類型的取值范圍 ??
  22. ???????? //?int?int_c?=?1L; ??
  23. ??
  24. ???????? //?可以把一個(gè)int型值直接賦值給long型變量,數(shù)字后無(wú)需后綴標(biāo)識(shí) ??
  25. ???????? long ?long_a?=? 1 ; ??
  26. ???????? //?如果給long型變量賦予的值超出了int型值的范圍,數(shù)字后必須加L(不區(qū)分大小寫)標(biāo)識(shí) ??
  27. ???????? long ?long_b?=?2200000000L; ??
  28. ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
  29. ???????? //?long?long_c?=?9300000000000000000L; ??
  30. ??
  31. ???????? //?可以把一個(gè)int型值直接賦值給float型變量 ??
  32. ???????? float ?float_a?=? 1 ; ??
  33. ???????? //?可以把一個(gè)long型值直接賦值給float型變量 ??
  34. ???????? float ?float_b?=?1L; ??
  35. ???????? //?沒有F(不區(qū)分大小寫)后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double型的,不能將它直接賦值給float型變量 ??
  36. ???????? //?float?float_c?=?1.0; ??
  37. ???????? //?float型數(shù)值需要有一個(gè)F(不區(qū)分大小寫)后綴標(biāo)識(shí) ??
  38. ???????? float ?float_d?=? 1 .0F; ??
  39. ???????? //?把一個(gè)double型值賦值給float型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出float類型的取值范圍 ??
  40. ???????? //?float?float_e?=?1.0D; ??
  41. ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
  42. ???????? //?float?float_f?=?3.5000000E38F; ??
  43. ??
  44. ???????? //?可以把一個(gè)int型值直接賦值給double型變量 ??
  45. ???????? double ?double_a?=? 1 ; ??
  46. ???????? //?可以把一個(gè)long型值直接賦值給double型變量 ??
  47. ???????? double ?double_b?=?1L; ??
  48. ???????? //?可以把一個(gè)float型值直接賦值給double型變量 ??
  49. ???????? double ?double_c?=?1F; ??
  50. ???????? //?不帶后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double類型的,可以直接賦值 ??
  51. ???????? double ?double_d?=? 1.0 ; ??
  52. ???????? //?也可以給數(shù)字增加一個(gè)D(不區(qū)分大小寫)后綴標(biāo)識(shí),明確標(biāo)出它是double類型的 ??
  53. ???????? double ?double_e?=? 1 .0D; ??
  54. ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
  55. ???????? //?double?double_f?=?1.8000000000000000E308D; ??
  56. ??
  57. ???????? //?把一個(gè)double型值賦值給一個(gè)byte類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出byte類型的取值范圍 ??
  58. ???????? //?byte?byte_d?=?1.0D; ??
  59. ???????? //?把一個(gè)double型值賦值給一個(gè)short類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出short類型的取值范圍 ??
  60. ???????? //?short?short_d?=?1.0D; ??
  61. ???????? //?把一個(gè)double型值賦值給一個(gè)int類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出int類型的取值范圍 ??
  62. ???????? //?int?int_d?=?1.0D; ??
  63. ???????? //?把一個(gè)double型值賦值給一個(gè)long類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出long類型的取值范圍 ??
  64. ???????? //?long?long_d?=?1.0D; ??
  65. ??
  66. ???????? //?可以用字符初始化一個(gè)char型變量 ??
  67. ???????? char ?char_a?=? 'a' ; ??
  68. ???????? //?也可以用一個(gè)int型數(shù)值初始化char型變量 ??
  69. ???????? char ?char_b?=? 1 ; ??
  70. ???????? //?把一個(gè)long型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 ??
  71. ???????? //?char?char_c?=?1L; ??
  72. ???????? //?把一個(gè)float型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 ??
  73. ???????? //?char?char_d?=?1.0F; ??
  74. ???????? //?把一個(gè)double型值賦值給一個(gè)char類型變量,編譯時(shí)會(huì)報(bào)錯(cuò),即使這個(gè)值沒有超出char類型的取值范圍 ??
  75. ???????? //?char?char_e?=?1.0D; ??
  76. ???????? //?編譯器會(huì)做范圍檢查,如果賦予的值超出了范圍就會(huì)報(bào)錯(cuò) ??
  77. ???????? //?char?char_f?=?70000; ??
  78. ????} ??
  79. }??
    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é)論:

  1. 未帶有字符后綴標(biāo)識(shí)的整數(shù)默認(rèn)為int類型;未帶有字符后綴標(biāo)識(shí)的浮點(diǎn)數(shù)默認(rèn)為double類型。
  2. 如果一個(gè)整數(shù)的值超出了int類型能夠表示的范圍,則必須增加后綴“L”(不區(qū)分大小寫,建議用大寫,因?yàn)樾懙腖與阿拉伯?dāng)?shù)字1很容易混淆),表示為long型。
  3. 帶有“F”(不區(qū)分大小寫)后綴的整數(shù)和浮點(diǎn)數(shù)都是float類型的;帶有“D”(不區(qū)分大小寫)后綴的整數(shù)和浮點(diǎn)數(shù)都是double類型的。
  4. 編譯器會(huì)在編譯期對(duì)byte、short、int、long、float、double、char型變量的值進(jìn)行檢查,如果超出了它們的取值范圍就會(huì)報(bào)錯(cuò)。
  5. int型值可以賦給所有數(shù)值類型的變量;long型值可以賦給long、float、double類型的變量;float型值可以賦給float、double類型的變量;double型值只能賦給double類型變量。


下圖顯示了幾種基本類型之間的默認(rèn)邏輯轉(zhuǎn)換關(guān)系:
JAVA面試題解惑系列(八)——聊聊基本類型(內(nèi)置類型)
圖中的實(shí)線表示無(wú)精度損失的轉(zhuǎn)換,而虛線則表示這樣的轉(zhuǎn)換可能會(huì)損失一定的精度。如果我們想把一個(gè)能表示更大范圍或者更高精度的類型,轉(zhuǎn)換為一個(gè)范圍更小或者精度更低的類型時(shí),就需要使用強(qiáng)制類型轉(zhuǎn)換(Cast)了。不過(guò)我們要盡量避免這種用法,因?yàn)樗3Rl(fā)錯(cuò)誤。請(qǐng)看下面的例子,如果不運(yùn)行代碼,你能預(yù)測(cè)它的結(jié)果嗎?

Java代碼 復(fù)制代碼
  1. public ? class ?PrimitiveTypeTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? int ?a?=? 123456 ; ??
  4. ???????? short ?b?=?( short )?a; ??
  5. ???????? //?b的值會(huì)是什么呢? ??
  6. ????????System.out.println(b); ??
  7. ????} ??
  8. }??
    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é)果:

  1. -7616


運(yùn)算符對(duì)基本類型的影響

當(dāng)使用+、-、*、/、%運(yùn)算符對(duì)基本類型進(jìn)行運(yùn)算時(shí),遵循如下規(guī)則:

  1. 只要兩個(gè)操作數(shù)中有一個(gè)是double類型的,另一個(gè)將會(huì)被轉(zhuǎn)換成double類型,并且結(jié)果也是double類型;
  2. 否則,只要兩個(gè)操作數(shù)中有一個(gè)是float類型的,另一個(gè)將會(huì)被轉(zhuǎn)換成float類型,并且結(jié)果也是float類型;
  3. 否則,只要兩個(gè)操作數(shù)中有一個(gè)是long類型的,另一個(gè)將會(huì)被轉(zhuǎn)換成long類型,并且結(jié)果也是long類型;
  4. 否則,兩個(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)看:

引用
short s1=1;s1=s1+1;有什么錯(cuò)?short s1=1;s1+=1;有什么錯(cuò)?


乍一看,覺得它們都應(yīng)該沒有錯(cuò)誤,可以正常運(yùn)行。我們來(lái)寫個(gè)例子試試:

Java代碼 復(fù)制代碼
  1. public ? class ?PrimitiveTypeTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? short ?s1?=? 1 ; ??
  4. ???????? //?這一行代碼會(huì)報(bào)編譯錯(cuò)誤 ??
  5. ???????? //?s1?=?s1?+?1; ??
  6. ???????? //?這一行代碼沒有報(bào)錯(cuò) ??
  7. ????????s1?=? 1 ?+? 1 ; ??
  8. ???????? //?這一行代碼也沒有報(bào)錯(cuò) ??
  9. ????????s1?+=? 1 ; ??
  10. ????} ??
  11. }??
    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ī)則:

  1. 只要兩個(gè)操作數(shù)中有一個(gè)是基本類型,就是比較它們的數(shù)值是否相等。
  2. 否則,就是判斷這兩個(gè)對(duì)象的內(nèi)存地址是否相等,即是否是同一個(gè)對(duì)象。


下面的測(cè)試?yán)觿t驗(yàn)證了以上的規(guī)則:

Java代碼 復(fù)制代碼
  1. public ? class ?EqualsTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? //?int類型用int類型初始化 ??
  4. ???????? int ?int_int?=? 0 ; ??
  5. ???????? //?int類型用Integer類型初始化 ??
  6. ???????? int ?int_Integer?=? new ?Integer( 0 ); ??
  7. ???????? //?Integer類型用Integer類型初始化 ??
  8. ????????Integer?Integer_Integer?=? new ?Integer( 0 ); ??
  9. ???????? //?Integer類型用int類型初始化 ??
  10. ????????Integer?Integer_int?=? 0 ; ??
  11. ??
  12. ????????System.out.println( "int_int?==?int_Integer結(jié)果是:" ??
  13. ????????????????+?(int_int?==?int_Integer)); ??
  14. ????????System.out.println( "Integer_Integer?==?Integer_int結(jié)果是:" ??
  15. ????????????????+?(Integer_Integer?==?Integer_int)); ??
  16. ????????System.out.println(); ??
  17. ????????System.out.println( "int_int?==?Integer_Integer結(jié)果是:" ??
  18. ????????????????+?(int_int?==?Integer_Integer)); ??
  19. ????????System.out.println( "Integer_Integer?==?int_int結(jié)果是:" ??
  20. ????????????????+?(Integer_Integer?==?int_int)); ??
  21. ????????System.out.println(); ??
  22. ??
  23. ???????? //?boolean類型用boolean類型初始化 ??
  24. ???????? boolean ?boolean_boolean?=? true ; ??
  25. ???????? //?boolean類型用Boolean類型初始化 ??
  26. ???????? boolean ?boolean_Boolean?=? new ?Boolean( true ); ??
  27. ???????? //?Boolean類型用Boolean類型初始化 ??
  28. ????????Boolean?Boolean_Boolean?=? new ?Boolean( true ); ??
  29. ???????? //?Boolean類型用boolean類型初始化 ??
  30. ????????Boolean?Boolean_boolean?=? true ; ??
  31. ??
  32. ????????System.out.println( "boolean_boolean?==?boolean_Boolean結(jié)果是:" ??
  33. ????????????????+?(boolean_boolean?==?boolean_Boolean)); ??
  34. ????????System.out.println( "Boolean_Boolean?==?Boolean_boolean結(jié)果是:" ??
  35. ????????????????+?(Boolean_Boolean?==?Boolean_boolean)); ??
  36. ????????System.out.println(); ??
  37. ????????System.out.println( "boolean_boolean?==?Boolean_Boolean結(jié)果是:" ??
  38. ????????????????+?(boolean_boolean?==?Boolean_Boolean)); ??
  39. ????????System.out.println( "Boolean_Boolean?==?boolean_boolean結(jié)果是:" ??
  40. ????????????????+?(Boolean_Boolean?==?boolean_boolean)); ??
  41. ????} ??
  42. }??
    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é)果:

  1. int_int == int_Integer結(jié)果是:true
  2. Integer_Integer == Integer_int結(jié)果是:false
  3. int_int == Integer_Integer結(jié)果是:true
  4. Integer_Integer == int_int結(jié)果是:true
  5. boolean_boolean == boolean_Boolean結(jié)果是:true
  6. Boolean_Boolean == Boolean_boolean結(jié)果是:false
  7. boolean_boolean == Boolean_Boolean結(jié)果是:true
  8. Boolean_Boolean == boolean_boolean結(jié)果是:true


為了便于查看,上例中變量命名沒有采用規(guī)范的方式,而是采用了“變量類型”+“_”+“初始化值類型”的方式。

Math.round()方法

java.lang.Math類里有兩個(gè)round()方法,它們的定義如下:

Java代碼 復(fù)制代碼
  1. public ? static ? int ?round( float ?a)?{ ??
  2. ???? //other?code ??
  3. } ??
  4. ??
  5. public ? static ? long ?round( double ?a)?{ ??
  6. ???? //other?code ??
  7. }??
    public static int round(float a) {
    //other code
}

public static long round(double a) {
    //other code
}

  


它們的返回值都是整數(shù),且都采用四舍五入法。運(yùn)算規(guī)則如下:

  1. 如果參數(shù)為正數(shù),且小數(shù)點(diǎn)后第一位>=5,運(yùn)算結(jié)果為參數(shù)的整數(shù)部分+1。
  2. 如果參數(shù)為負(fù)數(shù),且小數(shù)點(diǎn)后第一位>5,運(yùn)算結(jié)果為參數(shù)的整數(shù)部分-1。
  3. 如果參數(shù)為正數(shù),且小數(shù)點(diǎn)后第一位<5;或者參數(shù)為負(fù)數(shù),且小數(shù)點(diǎn)后第一位<=5,運(yùn)算結(jié)果為參數(shù)的整數(shù)部分。


我們可以通過(guò)下面的例子來(lái)驗(yàn)證:

Java代碼 復(fù)制代碼
  1. public ? class ?MathTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ????????System.out.println( "小數(shù)點(diǎn)后第一位=5" ); ??
  4. ????????System.out.println( "正數(shù):Math.round(11.5)=" ?+?Math.round( 11.5 )); ??
  5. ????????System.out.println( "負(fù)數(shù):Math.round(-11.5)=" ?+?Math.round(- 11.5 )); ??
  6. ????????System.out.println(); ??
  7. ??
  8. ????????System.out.println( "小數(shù)點(diǎn)后第一位<5" ); ??
  9. ????????System.out.println( "正數(shù):Math.round(11.46)=" ?+?Math.round( 11.46 )); ??
  10. ????????System.out.println( "負(fù)數(shù):Math.round(-11.46)=" ?+?Math.round(- 11.46 )); ??
  11. ????????System.out.println(); ??
  12. ??
  13. ????????System.out.println( "小數(shù)點(diǎn)后第一位>5" ); ??
  14. ????????System.out.println( "正數(shù):Math.round(11.68)=" ?+?Math.round( 11.68 )); ??
  15. ????????System.out.println( "負(fù)數(shù):Math.round(-11.68)=" ?+?Math.round(- 11.68 )); ??
  16. ????} ??
  17. }??
    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é)果:

  1. 小數(shù)點(diǎn)后第一位=5
  2. 正數(shù):Math.round(11.5)=12
  3. 負(fù)數(shù):Math.round(-11.5)=-11
  4. 小數(shù)點(diǎn)后第一位<5
  5. 正數(shù):Math.round(11.46)=11
  6. 負(fù)數(shù):Math.round(-11.46)=-11
  7. 小數(shù)點(diǎn)后第一位>5
  8. 正數(shù):Math.round(11.68)=12
  9. 負(fù)數(shù):Math.round(-11.68)=-12


根據(jù)上面例子的運(yùn)行結(jié)果,我們還可以按照如下方式總結(jié),或許更加容易記憶:

  1. 參數(shù)的小數(shù)點(diǎn)后第一位<5,運(yùn)算結(jié)果為參數(shù)整數(shù)部分。
  2. 參數(shù)的小數(shù)點(diǎn)后第一位>5,運(yùn)算結(jié)果為參數(shù)整數(shù)部分絕對(duì)值+1,符號(hào)(即正負(fù))不變。
  3. 參數(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)部的代碼:

Java代碼 復(fù)制代碼
  1. public ? static ? int ?round( float ?a)?{ ??
  2. ???? return ?( int )floor(a?+? 0 .5f); ??
  3. } ??
  4. ??
  5. public ? static ? long ?round( double ?a)?{ ??
  6. ???? return ?( long )floor(a?+? 0 .5d); ??
  7. }??
    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è)試就知道了:

Java代碼 復(fù)制代碼
  1. public ? class ?MathTest?{ ??
  2. ???? //?枚舉類型,Java5.0以上版本可用 ??
  3. ???? static ? enum ?enum_e?{ ??
  4. ????????A,?B ??
  5. ????} ??
  6. ??
  7. ???? public ? static ? void ?main(String[]?args)?{ ??
  8. ???????? //?byte ??
  9. ???????? byte ?byte_n?=? 0 ; ??
  10. ???????? switch ?(byte_n)?{ ??
  11. ???????? case ? 0 : ??
  12. ????????????System.out.println( "byte可以用于switch語(yǔ)句" ); ??
  13. ????????????</sp
分享到:
評(píng)論

JAVA面試題解惑系列(八)——聊聊基本類型(內(nèi)置類型)


更多文章、技術(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ì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 木兰县| 方正县| 石楼县| 五指山市| 武清区| 长葛市| 霍州市| 大埔区| 德钦县| 博乐市| 沙坪坝区| 临桂县| 台南县| 恩施市| 武山县| 青海省| 中超| 浏阳市| 东莞市| 泾阳县| 景宁| 泾源县| 罗城| 鄯善县| 禄丰县| 浑源县| 蒙阴县| 泰顺县| 永州市| 湘潭县| 兴化市| 温州市| 榆社县| 甘肃省| 伊通| 确山县| 手机| 扬州市| 晴隆县| 沁源县| 古田县|