資料型別以及資料型別的轉換
一、基本資料型別:
byte:Java中最小的資料型別,在記憶體中佔8位(bit),即1個位元組,取值範圍-128~127,預設值0
short:短整型,在記憶體中佔16位,即2個位元組,取值範圍-32768~32767,預設值0
int:整型,用於儲存整數,在內在中佔32位,即4個位元組,取值範圍-2147483648~2147483647,預設值0
long:長整型,在記憶體中佔64位,即8個位元組-2^63~2^63-1,預設值0L
float:浮點型,在記憶體中佔32位,即4個位元組,用於儲存帶小數點的數字(與double的區別在於float型別有效小數點只有6~7位),預設值0
double:雙精度浮點型,用於儲存帶有小數點的數字,在記憶體中佔64位,即8個位元組,預設值0
char:字元型,用於儲存單個字元,佔16位,即2個位元組,取值範圍0~65535,預設值為空
boolean:布林型別,佔1個位元組,用於判斷真或假(僅有兩個值,即true、false),預設值false
二、引用資料型別:
類、介面型別、陣列型別、列舉型別、註解型別。
區別:
基本資料型別在被建立時,在棧上給其劃分一塊記憶體,將數值直接儲存在棧上。
引用資料型別在被建立時,首先要在棧上給其引用(控制代碼)分配一塊記憶體,而物件的具體資訊都儲存在堆記憶體上,然後由棧上面的引用指向堆中物件的地址。
例如,有一個類Person,有屬性name,age,帶有參的構造方法,
Person p = new Person("zhangsan",20);
在記憶體中的具體建立過程是:
1.首先在棧記憶體中位其p分配一塊空間;
2.在堆記憶體中為Person物件分配一塊空間,併為其三個屬性設初值"",0;
3.根據類Person中對屬性的定義,為該物件的兩個屬性進行賦值操作;
4.呼叫構造方法,為兩個屬性賦值為"Tom",20;(注意這個時候p與Person物件之間還沒有建立聯絡);
5.將Person物件在堆記憶體中的地址,賦值給棧中的p;通過引用(控制代碼)p可以找到堆中物件的具體資訊。
相關知識:
靜態區: 儲存自動全域性變數和 static 變數(包括 static 全域性和區域性變數)。靜態區的內容在總個程式的生命週期內都存在,由編譯器在編譯的時候分配。
堆區: 一般由程式設計師分配釋放,由 malloc 系列函式或 new 操作符分配的記憶體,其生命週期由 free 或 delete 決定。在沒有釋放之前一直存在,直到程式結束,由OS釋放。其特點是使用靈活,空間比較大,但容易出錯
棧區: 由編譯器自動分配釋放,儲存區域性變數,棧上的內容只在函式的範圍內存在,當函式執行結束,這些內容也會自動被銷燬,其特點是效率高,但空間大小有限
文字常量區: 常量字串就是放在這裡的。 程式結束後由系統釋放。
三、資料型別的轉換:
(1)boolean型別不參與轉換
(2)預設轉換
A:從小到大
B:byte,short,char -- int -- long -- float -- double
C:byte,short,char之間不相互轉換,直接轉成int型別參與運算。
(3)強制轉換
A:從大到小
B:可能會有精度的損失,一般不建議這樣使用。
C:格式:
目標資料型別 變數名 = (目標資料型別) (被轉換的資料);
(4)思考題和麵試題:
A:下面兩種方式有區別嗎?
float f1 = 12.345f;
float f2 = (float)12.345;
答:有區別,float f1=12.345f定義一個float型別的變數,float f2 = (float)12.345是把double型別的12.345強制轉換為float型別的變數。
B:下面的程式有問題嗎,如果有,在哪裡呢?
byte b1 = 3;
byte b2 = 4;
byte b3 = b1 + b2;
byte b4 = 3 + 4;
答:byte b3 = b1 + b2;是有問題的因為兩個byte型別的變數相加首先會把byte提升為int再做加法運算再把結果int型別的結果賦值給byte型別的變數b3會有問題
而byte b4 = 3 + 4;沒問題是因為3+4是一個常量計算,然後把結果賦值給byte型別的b4,如果結果在byte的範圍之類就不會報錯,顯然byte的範圍是-127-128所以不會有問題。
C:下面的操作結果是什麼呢?
byte b = (byte)130;
答:結果是-126,
我們要想知道結果是什麼,就應該知道是如何進行計算的。
而我們又知道計算機中資料的運算都是補碼進行的。
而要得到補碼,首先要計算出資料的二進位制。
A:獲取130這個資料的二進位制。
00000000 00000000 00000000 10000010
這是130的原碼,也是反碼,還是補碼。
B:做擷取操作,截成byte型別的了。
10000010
這個結果是補碼。
C:已知補碼求原碼。
符號位 數值位
補碼: 1 0000010
反碼: 1 0000001
原碼: 1 1111110
D:字元參與運算
是查詢ASCII裡面的值
'a' 97
'A' 65
'0' 48
System.out.println('a'); 97
System.out.println('a' + 1);98
E:字串參與運算
這裡其實是字串的連線
System.out.println("hello"+'a'+1);helloa1
System.out.println('a'+1+"hello");98hello
System.out.println("5+5="+5+5);5+5=55
System.out.println(5+5+"=5+5");10=5+5