【轉】Java基礎資料型別 (Elementary Data Type)

來源:互聯網
上載者:User

標籤:

原文網址:http://blog.csdn.net/bingduanlbd/article/details/27790287

Java語言是靜態類型的(statical typed),也就是說所有變數和運算式的類型再編譯時間就已經完全確定。由於是statical typed,導致Java語言也是強型別(Strong typed)的。強型別意味著每個變數都具有一種類型,每個運算式具有一種類型,並且每種類型都是嚴格定義的,類型限制了變數可以hold哪些值,運算式最終產生什麼值。同時限制了這些值可以進行的操作類型以及操作的具體方式。所有的賦值操作,無論是顯式的還是在方法調用中通過參數傳遞,都要進行類型相容性檢查。

1. 資料類型:

在java原始碼中,每個變數都必須聲明一種類型(type)。有兩種類型:primitive type和reference type。參考型別引用對象(reference to object),而基本類型直接包含值(directly contain value)。因此,Java資料類型(type)可以分為兩大類:基本類型(primitive types)和參考型別(reference types)。primitive types 包括boolean類型以及數實值型別(numeric types)。numeric types又分為整型(integer types)和浮點型(floating-point type)。整型有5種:byte short int long char(char本質上是一種特殊的int)。浮點類型有float和double。關係整理一下如:

對象是動態建立的類執行個體或者動態建立的數組。The value of reference types are references to objects,而引用一般是指記憶體位址。所有的對象(包括數組)支援Object類中定義的方法。String literals are presented by String object.

 

java有兩種類型(type),與之相對應的是兩種資料的值(two kinds of data values that can be stored in variable, pass as arguments and returned by methods),這兩隻data values是:primitive values,reference values。也許這麼理解起來更方便(雖然不嚴謹),Java變數有兩種:primitive variable和reference variable,在變數中,它們分別儲存primitive value和reference value。

null是一種特殊的type,但是你不能聲明一個變數為null類型,null type的唯一取值就是null。null可以負值給任意的參考型別或者轉化成任意的參考型別。在實踐中,一般把null當做字面值(literal),這個字面值可是是任意的參考型別。

2. 基本類型:

Java為基本類型提供語言層級的支援,即已經在Java中預定義,用相應的保留關鍵字表示。基本類型是單個值,而不是複雜的對象,基本類型不是物件導向的,主要出去效率方面的考慮,但是同時也提供基本類型的對象版本,即基本類型的封裝器(wrapper)。可以直接使用這些基本類型,也可以使用基本類型構造數組或者其他自訂類型。基本類型具有明確的取值範圍和數學行為。

2.1 整型

整型有byte short int long char,分別用8、16、32、64、16bits表示。有些地方可能不會把char列入整型範疇,但本質上char類型是int的一個子集。整型的寬度不應該被看成整數所佔用的記憶體空間大小,而應當理解成定義為整型的變數或者運算式的行為。JVM可以自由使用它們希望的、任何大小的記憶體空間,只要類型的行為符合規範。byte short int long都是有符號的,用2的補碼(two‘s-complement)表示。而char用16位表示,它是無符號的,表示的是UTF-16編碼集。

2.1.1 byte

byte由1個位元組8位表示,是最小的整數類型。主要用於節省記憶體空間關鍵。當操作來自網路、檔案或者其他IO的資料流時,byte類型特別有用。取值範圍為:[-128, 127]. byte的預設值為(byte)0,如果我們試圖將取值範圍外的值賦給byte類型變數,則會出現編譯錯誤,例如 byte b = 128;這個語句是無法通過編譯的。一個有趣的問題,如果我們有個方法: public void test(byte b)。試圖這麼調用這個方法是錯誤的: test(0); 編譯器會報錯,類型不相容!!!我們記得byte b =0;這是完全沒有問題的,為什麼在這裡就出錯啦?

這裡涉及到一個叫字面值(literal)的問題,字面值就是表面上的值,例如整型字面值在原始碼中就是諸如 5 , 0, -200這樣的。如果整型子面子後面加上L或者l,則這個字面值就是long類型,比如:1000L代表一個long類型的值。如果不加L或者l,則為int類型。基本類型當中的byte short int long都可以通過不加L的整型字面值(我們就稱作int字面值吧)來建立,例如 byte b = 100; short s = 5;對於long類型,如果大小超出int所能表示的範圍(32 bits),則必須使用L結尾來表示。整型字面值可以有不同的表示方式:16進位【0X or 0x】、10進位【nothing】、八進位【0】2進位【0B or 0b】等,二進位字面值是JDK 7以後才有的功能。在賦值操作中,int字面值可以賦給byte short int long,Java語言會自動處理好這個過程。如果方法調用時不一樣,調用test(0)的時候,它能匹配的方法是test(int),當然不能匹配test(byte)方法,至於為什麼Java沒有像支援賦值操作那樣支援方法調用,不得而知。注意區別封裝器與原始類型的自動轉換(anto-boxing,auto-unboxing)。byte d = ‘A‘;也是合法的,字元字面值可以自動轉換成16位的整數。

更多關於字面值的介紹,參考oracle文檔(http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)。

對byte類型進行數學運算時,會自動提升為int類型,如果運算式中有double或者float等類型,也是自動提升。所以下面的代碼是錯誤的:

 

[java] view plaincopy 
  1. <span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">byte t s1 = 100;  
  2. byte s2 = ‘a‘;  
  3. byte sum = s1 + s2;//should cast by (byte)</span></span></span>  

 

2.1.2 short

用16為表示,取值範圍為:[- 2^15, 2^15 - 1]。short可能是最不常用的類型了。可以通過整型字面值或者字元字面值賦值,前提是不超出範圍(16 bit)。short類型參與運算的時候,一樣被提升為int或者更高的類型。(順序為 byte short int long float double).

2.1.3 int

32 bits, [- 2^31, 2^31 - 1].有符號的二進位補碼錶示的整數。常用語控制迴圈,注意byte 和 short在運算中會被提升為int類型或更高。Java 8以後,可以使用int類型表示無符號32位整數[ 0, 2^31 - 1]。

2.1.4 long

64 bits, [- 2^63, 2^63 - 1,預設值為0L].當需要計算非常大的數時,如果int不足以容納大小,可以使用long類型。如果long也不夠,可以使用BigInteger類。

2.1.5 char

16 bits, [0, 65535], [0, 2^16 -1],從‘\u0000‘到‘\uffff‘。無符號,預設值為‘\u0000‘。Java使用Unicode字元集表示字元,Unicode是完全國際化的字元集,可以表示全部人類語言中的字元。Unicode需要16位寬,所以Java中的char類型也使用16 bit表示。 賦值可能是這樣的:

char ch1 = 88;

char ch2 = ‘A‘;

ASCII字元集佔用了Unicode的前127個值。之所以把char歸入整型,是因為Java為char提供算術運算支援,例如可以ch2++;之後ch2就變成Y。當char進行加減乘除運算的時候,也被轉換成int類型,必須顯式轉化回來。

2.2 浮點類型

包含單精確度的float和雙精確度的double,分別用32、64bits表示,遵循IEEE 754規範。

2.2.1 float

使用32 bit表示,對應單精確度浮點數,運行速度相比double更快,占記憶體更小,但是當數值非常大或者非常小的時候會變得不精確。精度要求不高的時候可以使用float類型,聲明賦值樣本:

 

[java] view plaincopy 
  1. <span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-size:14px;"><span style="font-size:14px;">float f1 =10;  
  2. f1 = 10L;  
  3. f1 = 10.0f;  
  4. //f1 = 10.0;預設為double</span></span></span>  

可以將byte、short、int、long、char賦給float類型,java自動完成轉換。

 

2.2.2 double

64為表示,將浮點子面子賦給某個變數時,如果不顯示在字面值後面加f或者F,則預設為double類型。java.lang.Math中的函數都採用double類型。

如果double和float都無法達到想要的精度,可以使用BigDecimal類。

2.3 boolean類型

boolean類型只有兩個值true和false,預設為false。boolean與是否為0沒有任何關係,但是可以根據想要的邏輯進行轉換。許多地方都需要用到boolean類型。

3. 字面值

在Java原始碼中,字面值用於表示固定的值(fixed value)。數值型的字面值是最常見的,字串字面值可以算是一種,當然也可以把特殊的null當做字面值。字面值大體上可以分為整型字面值、浮點字面值、字元和字串字面值、特殊字面值。

3.1. 整型字面值

從形式上看是整數的字面值歸類為整型字面值。例如: 10, 100000L, ‘B‘、0XFF這些都可以稱為字面值。整型字面值可以用十進位、16、8、2進位來表示。十進位很簡單,2、8、16進位的表示分別在最前面加上0B(0b)、0、0X(0x)即可,當然基數不能超出進位的範圍,比如09是不合法的,八進位的基數只能到7。一般情況下,字面值建立的是int類型,但是int字面值可以賦值給byte short char long int,只要字面值在目標範圍以內,Java會自動完成轉換,如果試圖將超出範圍的字面值賦給某一類型(比如把128賦給byte類型),編譯通不過。而如果想建立一個int類型無法表示的long類型,則需要在字面值最後面加上L或者l。通常建議使用容易區分的L。所以整型字面值包括int字面值和long字面值兩種。

3.2. 浮點字面值

浮點字面值簡單的理解可以理解為小數。分為float字面值和double字面值,如果在小數後面加上F或者f,則表示這是個float字面值,如11.8F。如果小數後面不加F(f),如10.4。或者小數後面加上D(d),則表示這是個double字面值。另外,浮點字面值支援科學技術法表示。下面是一些例子:

 

[java] view plaincopy 
  1. <span style="font-family:Microsoft YaHei;font-size:14px;">double d1 = 10;  
  2. double d2  = 11.4;  
  3. double d3 = 1.23E3;  
  4. double d4 = 10D;  
  5. double d5 = 0.4D;  
  6. float f1 = 10;  
  7. float f2 = 11.1F;  
  8. float f3 = 1.23e-4F;  
  9. float f4 = 1.23E0F;</span>  

 

3.3 字元及字串字面值

Java中字元字面值用單引號括起來,如‘@’‘1’。所有的UTF-16字元集都包含在字元字面值中。不能直接輸入的字元,可以使用逸出字元,如‘\n’為換行字元。也可以使用八進位或者十六進位表示字元,八進位使用反斜線加3位元字表示,例如‘\141‘表示字母a。十六進位使用\u加上4為十六進位的數表示,如‘\u0061‘表示字元a。也就是說,通過使用逸出字元,可以表示鍵盤上的有的或者沒有的所有字元。常見的逸出字元序列有:

\ddd(八進位) 、 \uxxxx(十六進位Unicode字元)、\‘(單引號)、\"(雙引號)、\\ (反斜線)\r(斷行符號符) \n(分行符號) \f(換頁符) \t(定位字元) \b(回格符)

字串字面值則使用雙引號,字串字面值中同樣可以包含字元字面值中的逸出字元序列。字串必須位於同一行或者使用+運算子,因為java沒有續行逸出序列。

3.4 特殊字面值

null是一種特殊的類型(type),可以將它賦給任何參考型別變數,表示這個變數不引用任何東西。如果一個參考型別變數為null,表示這個變數不可用。

還有一種特殊的class literal,用type name加上.class表示,例如String.class。首先,String是類Class(java.lang.Class)的一個執行個體(對象),而"This is a string"是類String的一個對象。然後,class literal用於表示類Class的一個對象,比如String.class用於表示類Class的對象String。簡單地說,類子面子(class literal)就是諸如String.class 、Integer.class這樣的字面值,它所表示的就是累String、類Integer。如果輸出Integer.class,你會得到class java.lang.Integer。List.class的輸出為interface java.util.List。總之,class literal用於表示類型本身!

3.5 在數值型字面值中使用底線

JDK7開始,可以在數值型字面值(包括整型字面值和浮點字面值)插入一個或者多個底線。但是底線只能用於分隔數字,不能分隔字元與字元,也不能分隔字元與數字。例如 int x = 123_456_789.在編譯的時候,底線會自動去掉。可以連續使用底線,比如float f = 1.22___33__44.二進位或者十六進位的字面值也可以使用底線,記住一點,底線只能用於數字與數字之間,初次以外都是非法的。例如1._23是非法的,_123、11000_L都是非法的。

4. 基本類型之間的轉換

我們看到,將一種類型的值賦給另一種類型是很常見的。在Java中,boolean類型與所有其他7種類型都不能進行轉換,這一點很明確。對於其他7中數實值型別,它們之間都可以進行轉換,但是可能會存在精度損失或者其他一些變化。轉換分為自動轉換和強制轉換。對於自動轉換(隱式),無需任何操作,而強制類型轉換需要顯式轉換,即使用轉換操作符(type)。首先將7種類型按下面順序排列一下:

byte <(short=char)< int < long < float < double

如果從小轉換到大,可以自動完成,而從大到小,必須強制轉換。short和char兩種相同類型也必須強制轉換。

4.1 自動轉換

自動轉換時發生擴寬(widening conversion)。因為較大的類型(如int)要儲存較小的類型(如byte),記憶體總是足夠的,不需要強制轉換。如果將字面值儲存到byte、short、char、long的時候,也會自動進行類型轉換。注意區別,此時從int(沒有帶L的整型字面值為int)到byte/short/char也是自動完成的,雖然它們都比int小。在自動類型轉化中,除了以下幾種情況可能會導致精度損失以外,其他的轉換都不能出現精度損失。

》int--> float

》long--> float

》long--> double

》float -->double without strictfp

除了可能的精度損失外,自動轉換不會出現任何運行時(run-time)異常。

4.2 強制類型轉換

如果要把大的轉成小的,或者在short與char之間進行轉換,就必須強制轉換,也被稱作縮小轉換(narrowing conversion),因為必須顯式地使數值更小以適應目標類型。強制轉換採用轉換操作符()。嚴格地說,將byte轉為char不屬於narrowing conversion),因為從byte到char的過程其實是byte-->int-->char,所以widening和narrowing都有。強制轉換除了可能的精度損失外,還可能使模(overall magnitude)發生變化。強制轉換格式如下:

(target-type) value

 

[java] view plaincopy 
  1. <span style="font-family:Microsoft YaHei;font-size:14px;">int a=257;   
  2. byte b;   
  3. b = (byte)a;//1</span>  

 

如果整數的值超出了byte所能表示的範圍,結果將對byte類型的範圍取餘數。例如a=256超出了byte的[-128,127]的範圍,所以將257除以byte的範圍(256)取餘數得到b=1;需要注意的是,當a=200時,此時除了256取餘數應該為-56,而不是200.

將浮點類型賦給整數類型的時候,會發生截尾(truncation)。也就是把小數的部分去掉,只留下整數部分。此時如果整數超出目標類型範圍,一樣將對目標類型的範圍取餘數。

7中基本類型轉換總結如:

4.3 賦值及運算式中的類型轉換:4.3.1 字面值賦值

在使用字面值對整數賦值的過程中,可以將int literal賦值給byte short char int,只要不超出範圍。這個過程中的類型轉換時自動完成的,但是如果你試圖將long literal賦給byte,即使沒有超出範圍,也必須進行強制類型轉換。例如 byte b = 10L;是錯的,要進行強制轉換。

4.3.2 運算式中的自動型別提升

除了賦值以外,運算式計算過程中也可能發生一些類型轉換。在運算式中,型別提升規則如下:

》所有byte/short/char都被提升為int。

》如果有一個運算元為long,整個運算式提升為long。float和double情況也一樣。

【轉】Java基礎資料型別 (Elementary Data Type)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.