JAVA資料型別詳談

2020-10-05 11:01:10

變數和型別

變數指的是程式執行時可變的量,相當於開闢一塊記憶體空間來儲存一些資料型別則是對變數的種類進行了劃分, 不同的型別的變數具有不同的特性。

1.1整形變數

基本語法格式:

int 變數名 = 初始值;

程式碼範例:

int num = 10; //定義一個整型變數
System.out.println(num);

在java中,一個int變數佔4個位元組,這和C/C++不同,和作業系統沒有直接關係。
位元組是計算機中表示空間大小的基本單位.
計算機使用二進位制表示資料. 我們認為 8 個二進位制位(bit) 為一個位元組(Byte),4個位元組表示的資料範圍是 -2^31 到 2^31-1
注意:

  1. int 表示變數的型別是一個整型
  2. 變數名是變數的標識,後續都是通過這個名字來使用變數。
  3. Java 中 = 表示賦值(和數學不一樣), 意思是給變數設定一個初始值.
  4. 初始化操作是可選的, 但是建議建立變數的時候都顯式初始化.
  5. 最後不要忘記分號, 否則會編譯失敗。
  6. // 表示註釋. 註釋作為程式碼的解釋說明部分, 不參與編譯執行。
1.2長整型變數

基本語法格式:

long 變數名 = 初始值;

程式碼範例:

long num = 10L; //定義一個長整型變數,初始值寫作10l也可以(小寫L)
System.out.println(num);

注意:

  1. 基本語法格式和建立 int 變數基本一致,只是把型別修改成 long
  2. 初始化設定的值為 10L ,表示一個長整型的數位,10l 也可以.
  3. 使用 10 初始化也可以, 10 的型別是 int, 10L 的型別是 long, 使用 10 L 或者 10 l 更好一些.
  4. Java 中 long 型別佔 8 個位元組. 表示的資料範圍 -2^63 到 2^63-1。
1.3雙精度浮點型變數

基本語法格式:

double 變數名 = 初始值;

程式碼範例:

double num = 1.1;
System.out.println(num * num)
// 執行結果
1.2100000000000002

注意:
Java 中的 double 雖然也是 8 個位元組, 但是浮點數的記憶體佈局和整數差別很大, 不能單純的用 2 ^ n 的形式表示資料範圍。
Java 的 double 型別的記憶體佈局遵守 IEEE 754 標準(和C語言一樣), 嘗試使用有限的記憶體空間表示可能無限的小數, 勢必會存在一定的精度誤差。

1.4單精度浮點型變數

基本格式:

float 變數名 = 初始值;

程式碼範例:

float num = 1.0; //這樣寫是不對的,1.0預設為double型別
float num = 1.0f;    // 寫作 1.0F 也可以
System.out.println(num);

注意:
float 型別在 Java 中佔四個位元組, 同樣遵守 IEEE 754 標準. 由於表示的資料精度範圍較小, 一般在工程上用到浮點數都優先考慮 double, 不太推薦float。

1.5 字元型別變數

基本格式:

char 變數名 = 初始值;

程式碼範例:

char ch = 'A';

注意:

  1. Java 中使用 單引號 + 單個字母 的形式表示字元字面值.
  2. 計算機中的字元本質上是一個整數。在 C 語言中使用 ASCII 表示字元, 而 Java 中使用 Unicode 表示字元. 因此char型別佔用兩個位元組, 表示的字元種類更多, 包括中文。
  3. 執行 javac 的時候可能出現以下錯誤:
Test.java:3: 錯誤: 未結束的字元文字
 char ch = '鍛?';
            ^

此時我們在執行 javac 時加上 -encoding UTF-8 選項即可

javac -encoding UTF-8 檔名.java
1.6位元組型別變數

基本語法格式:

byte 變數名 = 初始值;

程式碼範例:

byte value = 0; 
System.out.println(value);

注意:

  1. 位元組型別表示的也是整數,只佔一個位元組, 表示範圍較小 ( -128 -> +127 )
  2. 位元組型別和字元型別互不相干
1.7短整型變數

基本語法格式:

short 變數名 = 初始值;

程式碼範例:

short value = 0; 
System.out.println(value);

注意:

  1. short 佔用 2 個位元組, 表示的資料範圍是 -32768 -> +32767,也就是-2^15 到 2^15-1
  2. 這個表示範圍比較小, 一般不推薦使用.
1.8布林型別變數

基本語法格式:

boolean 變數名 = 初始值;

程式碼範例:

boolean value = true; 
System.out.println(value);

注意:

  1. boolean 型別的變數只有兩種取值, true 表示真, false 表示假。
  2. Java 的 boolean 型別和 int 不能相互轉換, 不存在 1 表示 true, 0 表示 false 這樣的用法.
  3. boolean 型別有些 JVM 的實現是佔 1 個位元組,有些是佔一個位元位,這個沒有明確規定。
1.9字串型別變數

基本語法格式:

String 變數名 = "初始值";

程式碼範例:

String name = "zhangsan"; 
System.out.println(name);

注意:

  1. Java 使用 雙引號 + 若干字元 的方式表示字串字面值。
  2. 和上面的型別不同, String 不是基本型別, 而是參照型別。
  3. 字串中的一些特定的不太方便直接表示的字元需要進行跳脫。
    跳脫字元範例:
// 建立一個字串 My name is "張三" 
String name = "My name is \"張三\""; //  \" 跳脫為雙引號

跳脫字元有很多,詳情見 常見跳脫字元
字串的 **+**操作,表示字串拼接:

//字串拼接
String a = "hello"; 
String b = "world"; 
String c = a + b; 
System.out.println(c);
// 執行結果
helloworld

//還可以用字串和整數進行拼接:
String str = "result = "; 
int a = 10; 
int b = 20; 
String result = str + a + b; 
System.out.println(result); 
// 執行結果
result = 1020
//以上程式碼說明, 當一個 + 表示式中存在字串的時候, 都是執行字串拼接行為.因此我們可以很方便的使用System.out.println 同時列印多個字串或數位
但是注意:
int a = 10; 
int b = 20; 
System.out.println("a+b);
//執行結果是30 而不是1020
System.out.println("a+「 」+b);
//這樣列印出來的才是a和b的值
1.10變數的作用域

一般就是該變數能生效的範圍,一般是變數定義所在的程式碼塊(大括號)

1.11變數的命名規則

硬性指標:

  1. 一個變數名只能包含數位, 字母, 下劃線
  2. 數位不能開頭。
  3. 變數名是大小寫敏感的。即num和Num是兩個不同的變數.
    注意: 雖然語法上也允許使用中文/美元符($)命名變數,但是強烈不推薦這樣做。

軟性指標:

  1. 變數命名要具有描述性, 見名知意.
  2. 變數名不宜使用拼音(但是不絕對).
  3. 變數名的詞性推薦使用名詞.
  4. 變數命名推薦 小駝峰命名法, 當一個變數名由多個單詞構成的時候, 除了第一個單詞之外, 其他單詞首字母都大寫。
    小駝峰命名範例:
int maxValue = 100; 
String studentName = "張三";
1.12 常數

每種型別的變數也對應著一種相同型別的常數.常數指的是執行時型別不能發生改變.
常數主要有一下兩種體現形式:
1.字面值常數

10 // int 字面值常數(十進位制) 
010 // int 字面值常數(八進位制) 由數位 0 開頭. 010 也就是十進位制的 8 
0x10 // int 字面值常數(十六進位制) 由數位 0x 開頭. 0x10 也就是十進位制的 16 
10L // long 字面值常數. 也可以寫作 10l (小寫的L) 
1.0 // double 字面值常數. 也可以寫作 1.0d 或者 1.0D 
1.5e2 // double 字面值常數. 科學計數法表示. 相當於 1.5 * 10^2 
1.0f // float 字面值常數, 也可以寫作 1.0F 
true // boolen 字面值常數, 同樣的還有 false 
'a' // char 字面值常數, 單引號中只能有一個字元
"abc" // String 字面值常數, 雙引號中可以有多個字元.

2.final 關鍵字修飾的常數

final int a = 10; 
a = 20; // 編譯出錯. 提示 無法為最終變數a賦值

結論:常數不能在程式執行過程中發生修改。

1.13型別轉換

int 和 long/double 相互賦值:

int a=10;
long b=20;
a = b; //高型別向低型別轉換會編譯出錯,提示可能會損失精度
b = a; //低轉高 沒有問題,編譯通過

int a = 10; 
double b = 1.0; 
a = b; // 高型別向低型別轉換會編譯出錯,提示可能會損失精度
b = a; //編譯通過

int 和 boolean 相互賦值:

int a = 10; 
boolean b = true; 
b = a; // 編譯出錯, 提示不相容的型別
a = b; // 編譯出錯, 提示不相容的型別

int 字面值常數給byte賦值

byte a = 100; // 編譯通過
byte b = 256; //  超出該型別資料範圍會編譯報錯, 提示從int轉換到byte可能會有損失

結論:

  1. 不同數位型別的變數之間賦值,表示範圍小的型別可以隱式轉換成範圍較大的型別,反之則不行。
  2. int 和 boolean 是毫不相干的兩種型別,不能相互賦值。
  3. 注意byte表示的資料範圍是-128到+127,256已經超過範圍,使用字面常數賦值的時候,java會自動進行一些檢查校驗,判定賦值是否合理。
使用強制型別轉換:
int a = 0; 
double b = 10.5; 
a = (int)b; 
int a = 10; 
boolean b = false; 
b = (boolean)a; //編譯出錯,提示不相容的型別

結論:
使用 變數a = (型別)變數b 的方式可以將 double 型別強制轉成 int. 但是

  1. 強制型別轉換可能會導致精度丟失. 如剛才的例子中, 賦值之後, 10.5 就變成 10 了, 小數點後面的部分被忽略.
  2. 強制型別轉換不是一定能成功,互不相干的型別之間無法轉換。
1.14數值提升

int 和long 混合運算:

int a = 10; 
long b = 20; 
int c = a + b; // 編譯出錯, 提示將 long 轉成 int 會丟失精度
int c = (long)a + b;//使用強制型別轉換,編譯通過
long d = a + b; // 編譯通過.

結論:
當 int 和 long 混合運算的時候, int 會提升成 long, 得到的結果仍然是 long 型別, 需要使用 long 型別的變數來接收結果. 如果非要用 int 來接收結果, 就需要使用強制型別轉換.
byte 和 byte 的運算:

byte a = 10; 
byte b = 20; 
byte c = a + b; 
System.out.println(c); 
// 編譯報錯
Test.java:5: 錯誤: 不相容的型別: 從int轉換到byte可能會有損失
 byte c = a + b; 
 ^
 //正確寫法:
 byte c = (byte)(a + b); 

結論:
byte 和 byte 都是相同型別, 但是出現編譯報錯. 原因是, 雖然 a 和 b 都是 byte, 但是計算 a + b 會先將 a 和 b 都提升成 int, 再進行計算, 得到的結果也是 int, 這時賦給 c, 就會出現上述錯誤.由於計算機的 CPU 通常是按照 4 個位元組為單位從記憶體中讀寫資料. 為了硬體上實現方便, 諸如 byte 和 short 這種低於4 個位元組的型別, 會先提升成 int, 再參與計算。

1.15 int 和 String之間的相互轉化
int 轉成 String:
int num = 10; 
// 方法1 
String str1 = num + ""; 
// 方法2 
String str2 = String.valueof(num);
String 轉成 int
String str = "100"; 
int num = Integer.parseInt(str);
1.16 小結

在這裡插入圖片描述