天天看點

1、資料類型詳解

文章目錄

      • 一、基本資料類型 (原生類型)
        • (1)數值型
          • 整數型
          • 浮點型
        • (2)字元型
        • (3)布爾型
      • 二、引用資料類型
        • (1)數組類型 ( [ ] )
        • (2)類 (Class)
        • (3)接口 (Interface)
        • (4)枚舉
        • (5)注解
      • 三、存儲原理
      • 四、自動類型提升 - 低位元組到高位元組
        • (1)整型資料的自動類型提升
        • (2)字元型資料向整型資料的自動類型提升
        • (3)整型資料向浮點型資料的自動類型提升
        • (4)浮點型資料的自動類型提升
        • (5)其他資料類型
      • 五、強制類型轉換 - 高位元組到低位元組
        • (1)顯式的強制類型轉換 - TYPE a = (TYPE) b;
          • 1、高位整型、字元型向低位整型、字元型的強制類型轉換
          • 2、浮點型向整型的強制類型轉換
          • 3、高位浮點型向低位浮點型的強制類型轉換
        • (2)隐式的強制類型轉換

一、基本資料類型 (原生類型)

(1)數值型

整數型
  • byte

    • 1Byte;預設值 0;取值 -128 ~ 127
    • 封裝類:

      Byte

  • short

    • 2Byte;預設值 0;取值 -32768 ~ 32767
    • 封裝類:

      Short

  • int

    • 4Byte;預設值 0;取值 -2147483648 ~ 2147483647 (-2^32 ~ 2^(32-1) )
    • 封裝類:

      Integer

  • long

    • 8Byte;預設值 0;取值 -9223372036854775808 ~ 9223372036854775807
    • 封裝類:

      Long

浮點型
  • float

    • 4Byte;預設值 0.0f;取值 1.4E-45 ~ 3.402823E38
    • 封裝類:

      Float

  • double

    • 8Byte;預設值 0.0d;取值 4.9E-324 ~ 1.7976931348623157E308
    • 封裝類:

      Double

    • double類型可以精确的表示小數點後15位
  • 浮點數都是不精确的

(2)字元型

  • char

    • 2Byte;預設值 \u0000;取值 ‘\u0000’ ~ ‘\uFFFF’ (Unicode編碼) 即 0 ~ 65535,無符号
    • 封裝類:

      Character

    • 在計算機中,所有的字元在底層都存儲為整型,每個具體數字通過一張碼表映射為具體的字元。

      在Java中,char類型字元集為unicode編碼,char占 2個位元組16位,可以表示0~65535這個範圍中的65536個字元。是以char是無符号的,16位都用來表示數值大小。

(3)布爾型

  • boolean

    • 封裝類:

      Boolean

    • 預設值 false;取值 true false
      • 規範要求boolean類型的數值占 1bit
      • 雖然boolean表現出非0即1的特性,但是存儲空間的基本計量機關是位元組(Byte),不是位(bit),是以boolean至少占1個位元組
      • 不同JDK實作不同,JVM可能也會有自己的實作,比如有的boolean類型的變量當做int類型處理,也就是4個位元組
      • boolean類型的資料當做byte類型的數組處理,即boolean類型的數組裡每一個元素占1個位元組

二、引用資料類型

(1)數組類型 ( [ ] )

  • 數組是具有确定順序的若幹個相同類型的變量的集合
  • 數組可以定義成int,char,String等各種類型
  • 數組類型是從抽象基類Array派生的引用類型

(2)類 (Class)

  • String是一個特殊的類
    • String類的方法頭是:public final class String extends Object
    • 由于方法中有final關鍵字,是以java.lang.String類不可被繼承也不可被修改

(3)接口 (Interface)

(4)枚舉

(5)注解

三、存儲原理

  • 基本資料類型
    • 所有的簡單資料類型不存在“引用”的概念,基本資料都是直接存儲在記憶體中的記憶體棧上,資料本身的值就是存儲在棧空間裡
  • 引用類型
    • 引用類型繼承于Object類,使用Java記憶體堆和記憶體棧來進行這種類型的資料存儲,即“引用”是存儲在有序的記憶體棧上,而對象本身的值是存儲在記憶體堆上
  • 差別
    • 基本資料類型配置設定在棧上,引用類型配置設定在堆上

四、自動類型提升 - 低位元組到高位元組

  • 正向過程:

    byte->short->int->long->float->double

  • boolean不參與自動類型提升
    1、資料類型詳解

(1)整型資料的自動類型提升

  • 低位正數轉向高位正數時,高位址補0
  • 低位負整數提升為高位負整數時,先将低位負整數用補碼表示(所有的二進制整數在計算機底層都是以補碼儲存的,而負數需要轉化為原碼才能被我們識别,是以我們用進制轉換得到的是負數的原碼,需要除符号位外按位取反得到反碼,再+1得到補碼),再在低位負整數上進行符号位不變、高位補1的操作得到高位負整數的補碼。(若我們想轉為十進制,可以将補碼-1得到反碼,再除符号位外按位取反得到原碼,由原碼轉化為十進制)
  • 正負整型類型資料,進行自動類型提升時,對補碼進行符号擴充。

(2)字元型資料向整型資料的自動類型提升

  • char類型無論被提升為int還是long,都進行零擴充(即高位補0)

(3)整型資料向浮點型資料的自動類型提升

  • byte/short/char轉換為浮點型時,是通過int為跳闆進行轉換,即先轉換為對應的int類型,再進一步轉化為目标浮點類型
  • 32位浮點數float的底層存儲:第1位是數符S(表示底數的符号),2~9位為階碼E,最後23位為尾數M。)
  • 階碼E = 階數 + 移碼 127
  • 尾數M = 底數去掉整數部分

(4)浮點型資料的自動類型提升

  • float向double的自動類型提升規則:
  • 符号位 S :直接複制
  • 階碼 E:直接複制階數,但注意移碼有所不同。應該原階碼-127+1023才是正确的階碼
  • 尾數 M:直接複制原尾數,但由于double類型尾數為52位,是以需要在原尾數後補上29個0

(5)其他資料類型

  • short 和 char 都是16bit,不能實作【自動類型轉換】,但可以實作【自動類型提升】至 數字範圍較大的類型
  • boolean類型不能與任何數值型以及字元型資料類型互相轉換

五、強制類型轉換 - 高位元組到低位元組

(1)顯式的強制類型轉換 - TYPE a = (TYPE) b;

1、高位整型、字元型向低位整型、字元型的強制類型轉換
  • 整型向字元型轉換規則:若目标類型a的長度小于源類型b的長度,則在源類型b的低位直接截取目标類型a的長度的資料
  • 注意:計算機裡存儲的資料都是以補碼形式存儲的,需要變為原碼才能轉化為十進制。例如,若在截取低位時得到符号位為1的數,則此負數(補碼形式)需要-1(反碼形式)再按位取反得到原碼。原碼可通過計算機組成原理使我們便于直接了解并轉換為十進制
  • 整型轉char類型時,由于char類型是無符号的,是以不可能出現強制類型轉換後輸出為負的情況,是以同一個數強制類型轉換為short和char時,可能會出現結果不同
2、浮點型向整型的強制類型轉換
  • 規則:若不超過long或int的最大值,就省略小數部分直接指派;若超過long或int的最大值,那麼強制類型轉換後的結果就是long或int對應的最大值
  • 浮點型轉換為byte/char/short時,需要先以int為跳闆,即先轉換為int。再按整型的強制類型轉換規則,按目标類型長度截取低位數值。
  • 浮點型強制轉換為整型時,若沒有超出對應整型的範圍,則直接截取浮點數的整數部分進行指派。
3、高位浮點型向低位浮點型的強制類型轉換
  • double數值在float允許範圍内
    • float将會直接擷取符号位、階數(這裡需要将原階碼-1023再+127,因為float和double的移碼不相同),并根據浮點數的舍入規則,将double類型52位的尾數舍入為float類型的23位尾數。
  • double數值超出float允許範圍
    • 出現這種情況往往是因為階碼部分超出表示範圍。尾數隻決定精度,階碼才決定範圍。若出現這種情況,最後的結果将會輸出Infinity或-Infinity,也即正無窮和負無窮。但這并不是資料上的無窮,隻是因為浮點數存儲機制帶來的一種結果。

(2)隐式的強制類型轉換

  • 常發生在指派表達式和有傳回值的函數調用表達式中
    • 在指派表達式中,如果指派符左右兩側的操作數類型不同,則将指派符号右操作數強制轉換為指派符号左操作數的類型,然後進行指派
    • 在函數調用時,如果return後面的表達式的類型與函數傳回值類型不同,則在傳回值時将return後的表達式的數值強制轉換為函數傳回值所定義的類型,再将傳回值進行傳回
  • 這些強制轉換隻能當兩個類型可轉時才能進行
  • Java官方規定,【強制類型轉換】發生在int , long , float , double 之間,其餘類型不存在強制類型轉換,并且轉換時可能丢失精度或者溢出