亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

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

系統 2053 0

好東西分享

基本類型,或者叫做內置類型,是JAVA中不同于類的特殊類型。它們是我們編程中使用最頻繁的類型,因此面試題中也總少不了它們的身影,在這篇文章中我們將從面試中常考的幾個方面來回顧一下與基本類型相關的知識。

基本類型共有九種,它們分別都有相對應的包裝類。關于它們的詳細信息請看下表:

[img]http://zangweiren.iteye.com/upload/picture/pic/18450/8071c6c2-7cfb-3783-829a-a6abb3ae55e5.jpg [/img]

對于基本類型void以及它的包裝類java.lang.Void,我們都無法直接進行操作。基本類型可以分為三類,字符類型char,布爾類型boolean以及數值類型byte、short、int、long、float、double。數值類型又可以分為整數類型byte、short、int、long和浮點數類型float、double。JAVA中的數值類型不存在無符號的,它們的取值范圍是固定的,不會隨著機器硬件環境或者操作系統的改變而改變。對于數值類型的基本類型的取值范圍,我們無需強制去記憶,因為它們的值都已經以常量的形式定義在對應的包裝類中了。請看下面的例子:

Java代碼 復制代碼
  1. public ? class ?PrimitiveTypeTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? //?byte ??
  4. ????????System.out.println( "基本類型:byte?二進制位數:" ?+?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?二進制位數:" ?+?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?二進制位數:" ?+?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?二進制位數:" ?+?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?二進制位數:" ?+?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?二進制位數:" ?+?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?二進制位數:" ?+?Character.SIZE); ??
  47. ????????System.out.println( "包裝類:java.lang.Character" ); ??
  48. ???????? //?以數值形式而不是字符形式將Character.MIN_VALUE輸出到控制臺 ??
  49. ????????System.out.println( "最小值:Character.MIN_VALUE=" ??
  50. ????????????????+?( int )?Character.MIN_VALUE); ??
  51. ???????? //?以數值形式而不是字符形式將Character.MAX_VALUE輸出到控制臺 ??
  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 二進制位數:" + 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 二進制位數:" + 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 二進制位數:" + 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 二進制位數:" + 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 二進制位數:" + 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 二進制位數:" + 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 二進制位數:" + Character.SIZE);
		System.out.println("包裝類:java.lang.Character");
		// 以數值形式而不是字符形式將Character.MIN_VALUE輸出到控制臺
		System.out.println("最小值:Character.MIN_VALUE="
				+ (int) Character.MIN_VALUE);
		// 以數值形式而不是字符形式將Character.MAX_VALUE輸出到控制臺
		System.out.println("最大值:Character.MAX_VALUE="
				+ (int) Character.MAX_VALUE);
	}
}
  


運行結果:

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


Float和Double的最小值和最大值都是以科學記數法的形式輸出的,結尾的“E+數字”表示E之前的數字要乘以10的多少倍。比如3.14E3就是3.14×1000=3140,3.14E-3就是3.14/1000=0.00314。

大家將運行結果與上表信息仔細比較就會發現float、double兩種類型的最小值與Float.MIN_VALUE、Double.MIN_VALUE的值并不相同,這是為什么呢?實際上Float.MIN_VALUE和Double.MIN_VALUE分別指的是float和double類型所能表示的最小正數。也就是說存在這樣一種情況,0到±Float.MIN_VALUE之間的值float類型無法表示,0到±Double.MIN_VALUE之間的值double類型無法表示。這并沒有什么好奇怪的,因為這些范圍內的數值超出了它們的精度范圍。

基本類型存儲在棧中,因此它們的存取速度要快于存儲在堆中的對應包裝類的實例對象。從Java5.0(1.5)開始,JAVA虛擬機(Java Virtual Machine)可以完成基本類型和它們對應包裝類之間的自動轉換。因此我們在賦值、參數傳遞以及數學運算的時候像使用基本類型一樣使用它們的包裝類,但這并不意味著你可以通過基本類型調用它們的包裝類才具有的方法。另外,所有基本類型(包括void)的包裝類都使用了final修飾,因此我們無法繼承它們擴展新的類,也無法重寫它們的任何方法。

各種數值類型之間的賦值與轉換遵循什么規律呢?我們來看下面這個例子:

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

		// 給short類型變量賦值時,數字后無需后綴標識
		short short_a = 1;
		// 編譯器會做范圍檢查,如果賦予的值超出了范圍就會報錯
		// short short_b = 70000;
		// 把一個long型值賦值給short型變量,編譯時會報錯,即使這個值沒有超出short類型的取值范圍
		// byte short_c = 1L;

		// 給short類型變量賦值時,數字后無需后綴標識
		int int_a = 1;
		// 編譯器會做范圍檢查,如果賦予的值超出了范圍就會報錯
		// int int_b = 2200000000;
		// 把一個long型值賦值給int型變量,編譯時會報錯,即使這個值沒有超出int類型的取值范圍
		// int int_c = 1L;

		// 可以把一個int型值直接賦值給long型變量,數字后無需后綴標識
		long long_a = 1;
		// 如果給long型變量賦予的值超出了int型值的范圍,數字后必須加L(不區分大小寫)標識
		long long_b = 2200000000L;
		// 編譯器會做范圍檢查,如果賦予的值超出了范圍就會報錯
		// long long_c = 9300000000000000000L;

		// 可以把一個int型值直接賦值給float型變量
		float float_a = 1;
		// 可以把一個long型值直接賦值給float型變量
		float float_b = 1L;
		// 沒有F(不區分大小寫)后綴標識的浮點數默認為double型的,不能將它直接賦值給float型變量
		// float float_c = 1.0;
		// float型數值需要有一個F(不區分大小寫)后綴標識
		float float_d = 1.0F;
		// 把一個double型值賦值給float型變量,編譯時會報錯,即使這個值沒有超出float類型的取值范圍
		// float float_e = 1.0D;
		// 編譯器會做范圍檢查,如果賦予的值超出了范圍就會報錯
		// float float_f = 3.5000000E38F;

		// 可以把一個int型值直接賦值給double型變量
		double double_a = 1;
		// 可以把一個long型值直接賦值給double型變量
		double double_b = 1L;
		// 可以把一個float型值直接賦值給double型變量
		double double_c = 1F;
		// 不帶后綴標識的浮點數默認為double類型的,可以直接賦值
		double double_d = 1.0;
		// 也可以給數字增加一個D(不區分大小寫)后綴標識,明確標出它是double類型的
		double double_e = 1.0D;
		// 編譯器會做范圍檢查,如果賦予的值超出了范圍就會報錯
		// double double_f = 1.8000000000000000E308D;

		// 把一個double型值賦值給一個byte類型變量,編譯時會報錯,即使這個值沒有超出byte類型的取值范圍
		// byte byte_d = 1.0D;
		// 把一個double型值賦值給一個short類型變量,編譯時會報錯,即使這個值沒有超出short類型的取值范圍
		// short short_d = 1.0D;
		// 把一個double型值賦值給一個int類型變量,編譯時會報錯,即使這個值沒有超出int類型的取值范圍
		// int int_d = 1.0D;
		// 把一個double型值賦值給一個long類型變量,編譯時會報錯,即使這個值沒有超出long類型的取值范圍
		// long long_d = 1.0D;

		// 可以用字符初始化一個char型變量
		char char_a = 'a';
		// 也可以用一個int型數值初始化char型變量
		char char_b = 1;
		// 把一個long型值賦值給一個char類型變量,編譯時會報錯,即使這個值沒有超出char類型的取值范圍
		// char char_c = 1L;
		// 把一個float型值賦值給一個char類型變量,編譯時會報錯,即使這個值沒有超出char類型的取值范圍
		// char char_d = 1.0F;
		// 把一個double型值賦值給一個char類型變量,編譯時會報錯,即使這個值沒有超出char類型的取值范圍
		// char char_e = 1.0D;
		// 編譯器會做范圍檢查,如果賦予的值超出了范圍就會報錯
		// char char_f = 70000;
	}
}

  


從上面的例子中我們可以得出如下幾條結論:

  1. 未帶有字符后綴標識的整數默認為int類型;未帶有字符后綴標識的浮點數默認為double類型。
  2. 如果一個整數的值超出了int類型能夠表示的范圍,則必須增加后綴“L”(不區分大小寫,建議用大寫,因為小寫的L與阿拉伯數字1很容易混淆),表示為long型。
  3. 帶有“F”(不區分大小寫)后綴的整數和浮點數都是float類型的;帶有“D”(不區分大小寫)后綴的整數和浮點數都是double類型的。
  4. 編譯器會在編譯期對byte、short、int、long、float、double、char型變量的值進行檢查,如果超出了它們的取值范圍就會報錯。
  5. int型值可以賦給所有數值類型的變量;long型值可以賦給long、float、double類型的變量;float型值可以賦給float、double類型的變量;double型值只能賦給double類型變量。


下圖顯示了幾種基本類型之間的默認邏輯轉換關系:
JAVA面試題解惑系列(八)——聊聊基本類型(內置類型)
圖中的實線表示無精度損失的轉換,而虛線則表示這樣的轉換可能會損失一定的精度。如果我們想把一個能表示更大范圍或者更高精度的類型,轉換為一個范圍更小或者精度更低的類型時,就需要使用強制類型轉換(Cast)了。不過我們要盡量避免這種用法,因為它常常引發錯誤。請看下面的例子,如果不運行代碼,你能預測它的結果嗎?

Java代碼 復制代碼
  1. public ? class ?PrimitiveTypeTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? int ?a?=? 123456 ; ??
  4. ???????? short ?b?=?( short )?a; ??
  5. ???????? //?b的值會是什么呢? ??
  6. ????????System.out.println(b); ??
  7. ????} ??
  8. }??
    public class PrimitiveTypeTest {
	public static void main(String[] args) {
		int a = 123456;
		short b = (short) a;
		// b的值會是什么呢?
		System.out.println(b);
	}
}

  


運行結果:

  1. -7616


運算符對基本類型的影響

當使用+、-、*、/、%運算符對基本類型進行運算時,遵循如下規則:

  1. 只要兩個操作數中有一個是double類型的,另一個將會被轉換成double類型,并且結果也是double類型;
  2. 否則,只要兩個操作數中有一個是float類型的,另一個將會被轉換成float類型,并且結果也是float類型;
  3. 否則,只要兩個操作數中有一個是long類型的,另一個將會被轉換成long類型,并且結果也是long類型;
  4. 否則,兩個操作數(包括byte、short、int、char)都將會被轉換成int類型,并且結果也是int類型。


當使用+=、-=、*=、/=、%=、運算符對基本類型進行運算時,遵循如下規則:

  • 運算符右邊的數值將首先被強制轉換成與運算符左邊數值相同的類型,然后再執行運算,且運算結果與運算符左邊數值類型相同。


了解了這些,我們就能解答下面這個常考的面試題了。請看:

引用
short s1=1;s1=s1+1;有什么錯?short s1=1;s1+=1;有什么錯?


乍一看,覺得它們都應該沒有錯誤,可以正常運行。我們來寫個例子試試:

Java代碼 復制代碼
  1. public ? class ?PrimitiveTypeTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? short ?s1?=? 1 ; ??
  4. ???????? //?這一行代碼會報編譯錯誤 ??
  5. ???????? //?s1?=?s1?+?1; ??
  6. ???????? //?這一行代碼沒有報錯 ??
  7. ????????s1?=? 1 ?+? 1 ; ??
  8. ???????? //?這一行代碼也沒有報錯 ??
  9. ????????s1?+=? 1 ; ??
  10. ????} ??
  11. }??
    public class PrimitiveTypeTest {
	public static void main(String[] args) {
		short s1 = 1;
		// 這一行代碼會報編譯錯誤
		// s1 = s1 + 1;
		// 這一行代碼沒有報錯
		s1 = 1 + 1;
		// 這一行代碼也沒有報錯
		s1 += 1;
	}
}

  


從例子中我們可以看出結果了。利用上面列舉的規律,也很容易解釋。在s1=s1+1;中,s1+1運算的結果是int型,把它賦值給一個short型變量s1,所以會報錯;而在s1+=1;中,由于是s1是short類型的,所以1首先被強制轉換為short型,然后再參與運算,并且結果也是short類型的,因此不會報錯。那么,s1=1+1;為什么不報錯呢?這是因為1+1是個編譯時可以確定的常量,“+”運算在編譯時就被執行了,而不是在程序執行的時候,這個語句的效果等同于s1=2,所以不會報錯。前面講過了,對基本類型執行強制類型轉換可能得出錯誤的結果,因此在使用+=、-=、*=、/=、%=等運算符時,要多加注意。

當使用“==”運算符在基本類型和其包裝類對象之間比較時,遵循如下規則:

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


下面的測試例子則驗證了以上的規則:

Java代碼 復制代碼
  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結果是:" ??
  13. ????????????????+?(int_int?==?int_Integer)); ??
  14. ????????System.out.println( "Integer_Integer?==?Integer_int結果是:" ??
  15. ????????????????+?(Integer_Integer?==?Integer_int)); ??
  16. ????????System.out.println(); ??
  17. ????????System.out.println( "int_int?==?Integer_Integer結果是:" ??
  18. ????????????????+?(int_int?==?Integer_Integer)); ??
  19. ????????System.out.println( "Integer_Integer?==?int_int結果是:" ??
  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結果是:" ??
  33. ????????????????+?(boolean_boolean?==?boolean_Boolean)); ??
  34. ????????System.out.println( "Boolean_Boolean?==?Boolean_boolean結果是:" ??
  35. ????????????????+?(Boolean_Boolean?==?Boolean_boolean)); ??
  36. ????????System.out.println(); ??
  37. ????????System.out.println( "boolean_boolean?==?Boolean_Boolean結果是:" ??
  38. ????????????????+?(boolean_boolean?==?Boolean_Boolean)); ??
  39. ????????System.out.println( "Boolean_Boolean?==?boolean_boolean結果是:" ??
  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結果是:"
				+ (int_int == int_Integer));
		System.out.println("Integer_Integer == Integer_int結果是:"
				+ (Integer_Integer == Integer_int));
		System.out.println();
		System.out.println("int_int == Integer_Integer結果是:"
				+ (int_int == Integer_Integer));
		System.out.println("Integer_Integer == int_int結果是:"
				+ (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結果是:"
				+ (boolean_boolean == boolean_Boolean));
		System.out.println("Boolean_Boolean == Boolean_boolean結果是:"
				+ (Boolean_Boolean == Boolean_boolean));
		System.out.println();
		System.out.println("boolean_boolean == Boolean_Boolean結果是:"
				+ (boolean_boolean == Boolean_Boolean));
		System.out.println("Boolean_Boolean == boolean_boolean結果是:"
				+ (Boolean_Boolean == boolean_boolean));
	}
}

  


運行結果:

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


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

Math.round()方法

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

Java代碼 復制代碼
  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
}

  


它們的返回值都是整數,且都采用四舍五入法。運算規則如下:

  1. 如果參數為正數,且小數點后第一位>=5,運算結果為參數的整數部分+1。
  2. 如果參數為負數,且小數點后第一位>5,運算結果為參數的整數部分-1。
  3. 如果參數為正數,且小數點后第一位<5;或者參數為負數,且小數點后第一位<=5,運算結果為參數的整數部分。


我們可以通過下面的例子來驗證:

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

		System.out.println("小數點后第一位<5");
		System.out.println("正數:Math.round(11.46)=" + Math.round(11.46));
		System.out.println("負數:Math.round(-11.46)=" + Math.round(-11.46));
		System.out.println();

		System.out.println("小數點后第一位>5");
		System.out.println("正數:Math.round(11.68)=" + Math.round(11.68));
		System.out.println("負數:Math.round(-11.68)=" + Math.round(-11.68));
	}
}

  


運行結果:

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


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

  1. 參數的小數點后第一位<5,運算結果為參數整數部分。
  2. 參數的小數點后第一位>5,運算結果為參數整數部分絕對值+1,符號(即正負)不變。
  3. 參數的小數點后第一位=5,正數運算結果為整數部分+1,負數運算結果為整數部分。


但是上面的結論仍然不是很好記憶。我們來看看round()方法的內部實現會給我們帶來什么啟發?我們來看這兩個方法內部的代碼:

Java代碼 復制代碼
  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);
}

  


看來它們都是將參數值+0.5后交與floor()進行運算,然后取返回值。那么floor()方法的作用又是什么呢?它是取一個小于等于參數值的最大整數。比如經過floor()方法運算后,如果參數是10.2則返回10,13返回13,-20.82返回-21,-16返回-16等等。既然是這樣,我們就可以用一句話來概括round()方法的運算效果了:

  • Math類的round()方法的運算結果是一個<=(參數值+0.5)的最大整數。


switch語句

哪些類型可以用于switch語句的判斷呢?我們做個測試就知道了:

Java代碼 復制代碼
  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語句" ); ??
  13. ????????????</sp
分享到:
評論

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人国产三级精品 | 91精品国产91久久久久久 | 国产一区二区三区在线免费 | 亚洲爱婷婷色婷婷五月 | 亚洲你懂得| 国产一级片子 | 日本不卡视频在线 | 国产久爱青草视频在线观看 | 欧美精品国产综合久久 | 色综合视频在线观看 | 香蕉成人影院 | 极品粉嫩粉嫩福利视频在线 | 天天拍拍天天爽免费视频 | 色综合天天色综合 | 日韩婷婷 | 青青青国产免费线在 | 国产福利91精品一区二区 | 日本一区二区三区中文字幕 | 日本久色| 中国性猛交xxxx乱大交 | 国产毛片a级 | 欧美freesex10一|3 | 欧美黄色a | 久久综合久色欧美婷婷 | 99久久综合国产精品免费 | 幸福宝色多多 | 精品乱人伦一区二区 | 国产精品麻豆高清在线观看 | 四虎影视在线影院4hu | 天天操天天艹 | 色综合久久久久综合体桃花网 | 国产精品9999久久久久仙踪林 | 国内精品久久久久久久 | 欧美成人特黄级毛片 | 福利视频不卡 | 天天插天天射天天干 | 亚洲综合一区二区三区四区 | 久久伊人影院 | 99久久精品一区二区三区 | 亚洲人成影院午夜网站 | 毛片爱做的片 |