Java之路:基本資料型別
基本資料型別
在Java中,資料型別一共分為兩大類:基本資料型別、引用資料型別。由於引用資料型別較難理解,所以在此先介紹基本資料型別。
基本資料型別由Java語言定義,不可以再進行劃分。基本資料型別的資料佔用記憶體的大小固定,在記憶體中存入的是數值本身,而引用資料型別在記憶體中存入的是引用資料的存放地址,並不是資料本身。
基本資料型別是一個單純的資料型別,它表示的是一個具體數字、字元或邏輯值。
在Java中規定了8種基本資料型別來儲存整數、浮點數、字元和布林值,如下圖所示:
一個變數就如同一個杯子或一個容器,在期內要裝載某個特定的數值(如同杯子可以盛水)。杯子有大有小,盛的水也有多有少。同樣,不同型別的變數,其能表示的資料範圍也是不同的。
Java基本資料型別佔用記憶體位數及可表示的資料範圍如下表所示:
1、整數型別(Integer)
定義:整數型別,簡稱整型,表示的是不帶有小數點的數字。例如:10,20等。
分類:byte型別、short型別、int型別、long型別,預設情況下為int型別。可以以二進位制、八進位制、十進位制和十六進位制表示。
(1)byte型別
在Java中,byte型別佔據1位元組內(8個bit)存空間,取值範圍為-128(-27) ~ 127(27-1),下面讓我們來看看byte的具體使用方法:
public class ByteDemo {
public static void main(String[] args) {
byte byteMax = Byte.MAX_VALUE; // 獲取byte型別最大值
System.out.println("byte型別最大值:" + byteMax);
byte byteMin = Byte.MIN_VALUE; // 獲取byte型別最小值
System.out.println("byte型別最小值:" + byteMin);
byte byteSize = Byte.SIZE; // 獲取byte型別大小
System.out.println("byte型別大小:" + byteSize);
byte b = 20; // 定義一個byte型別資料
System.out.println("b的值是:" + b);
}
}
【結果】
在上面的例子中,變數b的值是20,在byte型別的取值範圍(-128 ~ 127)內,但如果不在這個範圍內呢?
public class ByteDemo {
public static void main(String[] args) {
byte b = 128; // 定義一個byte型別資料
System.out.println("b的值是:" + b);
}
}
【結果】
可以看出,128超出了byte型別的取值範圍。
解決方法就是擴充資料操作範圍:可以將byte擴充為範圍比它更大的short、int或long。即重新將變數b宣告成short、int或long型別。
(2)short型別
在Java中,short型別佔據2位元組內(16個bit)存空間,取值範圍為-32768(-215) ~ 32767(215-1),short的具體用法與byte基本相同,這裡不再贅述。
(3)int型別
在Java中,int型別佔據4位元組內(32個bit)存空間,取值範圍為-231 ~ 231-1,下面具體看一下int型別的用法:
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 獲取int型別最大值
System.out.println("int型別最大值:" + intMax);
int intMin = Integer.MIN_VALUE; // 獲取int型別最小值
System.out.println("int型別最小值:" + intMin);
int intSize = Integer.SIZE; // 獲取int型別大小
System.out.println("int型別大小:" + intSize);
int i = 127; // 定義一個int型別資料
System.out.println("i的值是:" + i);
}
}
【結果】
下面再看一個有趣的例子:
public class IntDemo {
public static void main(String[] args) {
byte b1 = Byte.MAX_VALUE + 1; // byte型別最大值加1
byte b2 = Byte.MIN_VALUE - 1; // byte型別最小值減1
short s1 = Short.MAX_VALUE + 1; // short型別最大值加1
short s2 = Short.MIN_VALUE - 1; // short型別最小值減1
System.out.println(b1);
System.out.println(b2);
System.out.println(s1);
System.out.println(s2);
}
}
【結果】
可以看出,結果全部超出取值範圍。
解決方法同樣是擴充資料操作範圍:可以將byte或short擴充為範圍比它更大的int或long。
那麼int型別又怎麼樣呢?
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 獲取int型別最大值
System.out.println("int型別最大值:" + intMax);
int intMin = Integer.MIN_VALUE; // 獲取int型別最小值
System.out.println("int型別最小值:" + intMin);
int i1 = Integer.MAX_VALUE + 1; // int型別最大值加1
System.out.println("int型別最大值加1是:" + i1);
int i2 = Integer.MIN_VALUE - 1; // int型別最大值加1
System.out.println("int型別最小值減1是:" + i2);
}
}
【結果】
可以看出,int型別最大值加1結果不會溢位,只是變成了最小值;最小值減1,結果會變成最大值。
以下是二進位制表示:
package data_type;
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 獲取int型別最大值
System.out.println("int型別最大值二進位制: " + Integer.toBinaryString(intMax));
int intMin = Integer.MIN_VALUE; // 獲取int型別最小值
System.out.println("int型別最小值二進位制: " + Integer.toBinaryString(intMin));
int i1 = Integer.MAX_VALUE + 1; // int型別最大值加1
System.out.println("int型別最大值+1二進位制: " + Integer.toBinaryString(i1));
int i2 = Integer.MIN_VALUE - 1; // int型別最大值加1
System.out.println("int型別最小值-1二進位制: " + Integer.toBinaryString(i2));
}
}
【結果】
資料最大值、最小值會出現一個迴圈過程,這種情況稱為資料溢位(overflow)。
而解決溢位的方法就是擴大資料的操作範圍,將int擴充為long型別。
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 獲取int型別最大值
System.out.println("int型別最大值:" + intMax);
int intMin = Integer.MIN_VALUE; // 獲取int型別最小值
System.out.println("int型別最小值:" + intMin);
int i1 = Integer.MAX_VALUE + 1; // int型別最大值加1
System.out.println("int型別最大值加1是:" + i1);
int i3 = Integer.MAX_VALUE + 2; // int型別最大值加2
System.out.println("int型別最大值加2是:" + i3);
int i2 = Integer.MIN_VALUE - 1; // int型別最大值加1
System.out.println("int型別最小值減1是:" + i2);
int i4 = Integer.MIN_VALUE - 2; // int型別最大值加2
System.out.println("int型別最大值減2是:" + i4);
}
}
【結果】
(4)long型別
在Java中,long型別佔據4位元組內(64個bit)存空間,取值範圍為-263 ~ 263-1,下面具體看一下long型別的用法:
注:為一個long型別的變數賦值時需要注意一點,所賦值的後面要加上一個“L”或“l”,說明賦值為long型別。但如果賦的值未超出int型的取值範圍,則可省略“L”或“l”。
public class LongDemo {
public static void main(String[] args) {
long longMax = Long.MAX_VALUE; // 獲取long型別最大值
System.out.println("long型別最大值:" + longMax);
long longMin = Long.MIN_VALUE; // 獲取long型別最小值
System.out.println("long型別最小值:" + longMin);
long longSize = Long.SIZE; // 獲取long型別大小
System.out.println("long型別大小:" + longSize);
long l1 = Long.MAX_VALUE + 1; // long型別最大值加1
System.out.println("long型別最大值加1是:" + l1);
long l3 = Long.MAX_VALUE + 2; // long型別最大值加2
System.out.println("long型別最大值加2是:" + l3);
long l2 = Long.MIN_VALUE - 1; // long型別最大值加1
System.out.println("long型別最小值減1是:" + l2);
long l4 = Long.MIN_VALUE - 2; // long型別最大值加2
System.out.println("long型別最大值減2是:" + l4);
}
}
【結果】
可以看出,long和int型別一樣結果產生溢位。
2、浮點型別
定義:浮點型資料主要用來表示的是帶有小數點的數字。例如:10.3,20.02等。
分類:float型別(單精度)、double型別(雙精度)。
(1)float型別
在Java中,float型別佔據4位元組記憶體空間,共32個bit,第1位為符號位,中間8位表示指數,最後23位表示尾數。
下面我們來看下float型別的使用:
public class FloatDemo {
public static void main(String[] args) {
float f = 3.0f;
System.out.println(f + " * " + f + " = " + f*f);
}
}
【結果】
注:含小數的實數預設為double型別資料,如果定義的是float型資料,為其賦值時必須要執行強制轉換,方法如下
// 1、直接在數字後加上“f”或“F”
float f1 = 3.0f;
// 2、直接在數字前面加強制轉換
float f2 = (float)1.2;
(2)double型別
在Java中,double型別佔據8位元組記憶體空間,共64個bit。
下面我們來看下double型別的使用:
public class DoubleDemo {
public static void main(String[] args) {
float fMax = Float.MAX_VALUE;
float fMin = Float.MIN_VALUE;
double dMax = Double.MAX_VALUE;
double dMin = Double.MIN_VALUE;
System.out.println("float型別最大值:" + fMax);
System.out.println("float型別最小值:" + fMin);
System.out.println("double型別最大值:" + dMax);
System.out.println("double型別最小值:" + dMin);
}
}
【結果】
float f = 2.456e67; // 錯誤,超出float可表示範圍
double d1 = 1.8e308; // 錯誤,超出double可表示範圍
2、字元型別(Char)
定義:即字母和符號的統稱。
字元型別在記憶體中佔有2個位元組,8個bit。使用方法如下:
public class CharDemo {
public static void main(String[] args) {
char c1 = 'a'; // 可以是字母
char c2 = '中'; // 可以是漢字
char c3 = 97; // 可以是數字,ASCII碼中97對應字母'a'
int i = 'a'; // char轉int
System.out.println(c1 + "\n" + c2 + "\n" + c3 + "\n" + i);
}
}
【結果】
注1:字元要用一對單引號(’’)括起。
注2:Java之中預設採用的編碼方式是Unicode編碼,此編碼是一種採用十六進位制編碼方案,可以表示出世界上任意的文字資訊。所以,在Java中,單個字元裡面是可以儲存中文字元的。而在C/C++中,中文字元只能當作字串處理。
注3:char和int型資料的互相轉換問題,遵循C語言常用的ASCII碼習慣,大寫字母A ~ Z 對應65 ~ 90、小寫字母a ~ z對應整數97 ~ 122、字元0 ~ 9對應49 ~57。
3、布林型別(boolean)
在Java中使用關鍵字boolean來宣告布林型別。被宣告為布林型別的變數,只有true(真)和false(假)兩種。除此之外,沒有其他的值可以賦值給這個變數。
public class BoolDemo {
public static void main(String[] args) {
boolean bool = true;
if(bool)
System.out.println("I love Java!");
}
}
基本資料型別的預設值
在Java中,若在變數的宣告時沒有賦初值,則會給該變數賦預設值。下表列出了各種型別的預設值。
基本資料型別的轉換
1、自動型別轉換
自動轉換條件
(1)轉換前後的資料型別要相互相容。
(2)轉換後的資料型別的表示範圍小於轉換前的型別。即擴大轉換。
注1:Java中,由於boolean型別只能存放true或false,與數字及字元不相容,因此,boolean型別不能與其他任何資料型別進行轉換。
注2:Java在進行數值運算時,以儘量不損失精度(正確性)為準則。
例如:一個字元型變數(本質上是2Byte大小的整數)與一個整型變數(預設4Byte大小的整數)進行運算,在運算前,不同型別的運算元需要先轉化成同一資料型別,然後再運算。因此,要先將字元型的變數轉換為整型變數,否則將4位元組整型變數轉換為2位元組的字元型,很有可能導致整型變數的值會溢位,從而導致計算錯誤。字元與整數是可使用自動型別轉換的。
假設參與某種運算有兩個不同的運算元(運算元1和運算元2),二者具有不同的資料型別,在運算操作之前,它們需要轉換為同一資料型別,其相互轉換的規則如下表所示。
下面看個例子:當兩個數中有一個為浮點數時,其運算的結果會有什麼樣的變化。
public class Demo {
public static void main(String[] args) {
int a = 152;
float b = 24.1f;
System.out.println("a = " + a + "\n" + "b = " + b);
System.out.println("a/b = " + a/b);
}
}
【結果】
【結果分析】
從執行的結果可以看出,當兩個數中有一個為浮點數時,其運算的結果會直接轉換為浮點數。
當表示式中變數的型別不同時,Java會自動把較小的表示範圍轉換成較大的表示範圍後,再做運算。也就是說,假設有一個整數和雙精度浮點數作運算,Java會把整數轉換成雙精度浮點數後再做運算,運算結果也會變成雙精度浮點數。
2、強制型別轉換
【語法】
(欲轉換的資料型別)變數名;
【例】
public class DefaultDemo {
public static void main(String[] args) {
int a = 152, b = 9;
float f1, f2, f3, f4;
System.out.println("a = " + a + "\n" + "b = " + b);
f1 = a/b;
f2 = (float)a/b; // 將整數a強制轉換為浮點數,再與b相除
f3 = a/(float)b; // 將整數b強制轉換為浮點數,再以a除之
f4 = (float)a/(float)b; // 將整數a,b同時強制轉換為浮點數,再相除
System.out.println("f1 = a/b = " + f1);
System.out.println("f2 = (float)a/b = " + f2);
System.out.println("f3 = a/(float)b = " + f3);
System.out.println("f4 = (float)a/(float)b = " + f4);
}
}
【結果】
【結果分析】
當兩個整數相除時,小數點後的數字會被截斷(並不四捨五入),使得運算結果為整數。要想得到浮點數,必須將其中一個或兩個數轉換為浮點數。
注:若將一個超出該變數可表示範圍的值賦給這個變數,這種轉換稱為縮小轉換。由於在轉換的過程中可能會丟失資料的精確度,因此Java並不會“自動”做這些型別的轉換,此時就必須要做強制性的轉換,例如 int x = (int)10.35(結果x=10),將double型別的值(10.35)強制轉換為int型別(10),這樣也丟失了很多的資訊。