B站400萬播放量的Java教程都講了什麼-學習筆記04-數據類型

8種類型概述

  • 整型
    • byte
    • short
    • int
    • long
  • 浮點型
    • float
    • double
  • 布爾型
    • boolean
  • 字符型
    • char

8種數據類型佔用內存空間

現代計算機通過集成電路的電信號控制開關,只能識別0/1,例如0101000…,

十進制 0 1 2 3
二進制 0 1 10 11

bit是計算機可以識別的最小單位,表示二進制的0/1,有如下的換算關係:

1Byte(字節)= 8bit(比特位) = 8位的0/1
1Kb = 1024 Byte
1Mb = 1024 Kb
1Gb = 1024 Mb
1Tb = 1024 Gb
1Pb = 1024 Tb
1Zb = 1024 Pb

  • 每種數據類型的存儲空間,具體原理請參見下文在這裏插入圖片描述

  • 若聲明類型時未賦值則8種數據類型的默認值都像0看齊

  • char 默認字符\u0000表示空字符(非空格)

  • 十進制和二進制轉換

    • 十進制轉成二進制:除2取餘,逆序輸出
       2|6 0
         2|3 0
           2|1 1
            2|0 1
12=1100=0*2^0+1*2+1*2^2+1*2^3
  • 二進制轉化成十進制
    01111111=1*2^0+1*2^1+1*2^3+1*2^4+1*2^5+1*2^6+0*2^7=127

Java中的數字類型,數字都有正負之分,所以在二進制中有一個符號位,在二進制的最左邊,0表示正數,1表示負數。

  • 不同數據類型的取值範圍的由來
    byte類型爲例,byte佔8個比特位,最大值是0111 1111,由前面可知換算成十進制是127
    byte最小值是-128(和原碼、反碼和補碼有關)
  • 其他進制
    • 十進制 0 1 2 3 4 5 6 7 8 9
    • 二進制 0 1 10 11 100…
    • 八進制 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20
    • 十六進制 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20
  • 處理字符
    計算機善於處理計算關係,但現實中的文字和語言十分多樣,計算機無法直接轉化成二進制,需要人爲的制定字符編碼表:
    計算機最初只支持英文,例如

‘a’ --97-- 01100001
‘A’ --65
‘0’ --48

‘a’ --按照ASII解碼–> 01100001
01100001 --按照ASII編碼–> ‘a’
當編碼和解碼採用同一種字典/對照表時,不會出現亂碼
當編碼和解碼採用不同一種字典/對照表時,可能會出現亂碼
字典的薄厚(不同的編碼系統)決定了存儲字符對應關係的多少:

  • 中文編碼:GBK2312< GBK <GB18030
  • 全球編碼unicode
    • UTF-8:比較節省空間
    • UTF-16
    • UTF-32
  • Java採用的是unicode編碼,因此標誌符可以使用中文(不建議使用)

字符型

  • 字符型包括字符和字符串類型
  • 字符通過''包裹,字符串通過""包裹,二者不兼容,Java一個字符包括2個字節,而中文恰好是一個字符佔2個字節,因此可以存儲中文文字,例如char a = 'a'; char b = '帥',但是char a = "a"不行,因爲"a"是字符串不能賦值到char類型
  • 通過'\'轉義,轉義字符也屬於char類型
    • \nSystem.out.print輸出不換行,System.out.println換行
    • \t製表符
    • \\ \本身
    • \' '本身
    • \" "本身
    • \u \u表示16進制的unicode編碼\u4e2d表示漢字“中” 可通過native2ascii命令將字符轉換成16進制

整數型

  • Java語言中的“字面值”被默認當作int, 如果想要其變成long需要在後面加上l/L(建議L )

  • 字面值可以以三種方式開始,但輸出默認爲十進制

    • 10進制:常用
    • 以0開頭的8進制,010
    • 以0x開頭的16進制,0x10
  • 類型自動轉換

    • long x = 888;//888 int字面值賦值給長整型的x,小容量可以自動轉換成大容量
    • long x = 2147483648;//右邊的值2147483648默認當作int,本身超出int 4個字節的容量,因此還未賦值給左邊的long型就會導致錯誤(面試題目)
    • long x = 2147483648L;添加L使得變成long型
  • 大容量無法自動轉換成小容量數值,需要通過(TYPE)強制轉換,但可能嚴重損失精度
    long x = 100L;//將100變爲長整型並賦值給長整型x
    int y = x;//將長整型賦值給整型,小的存不了大的,轉換失敗,大容量無法自動轉換成小容量
    int y = (int) x;//先強制將長整型x轉換成整型再賦值給整型y,可能會丟失精度

  • 大數轉小數的時候爲什麼會損失精度?
    這要從大數轉小數的原理出發,例如int x = 100L強制將8字節的長整型100轉換成4個字節的整型,其過程如下
    100L:00000000 00000000 00000000 00000000 00000000 00000000 00000000 01100100
    要將其轉換成4個字節的int,計算機會從前面砍掉4個字節,因此剩下:
    00000000 00000000 00000000 01100100
    而該值換算後還是100,並未損失精度;
    但是int x = 2147483648L,按照同樣的步驟轉換:
    2147483648L:00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000
    ,強制轉換爲4個字節的整型即截掉前面4個字節,此時剩下:
    10000000 00000000 00000000 00000000,很明顯這是一個負數,實際上是-2147483648,可見損失精度之大

  • 總結來說,若待轉換的數據並未超過轉換之後範圍,是不會損失精度的,但是若超過了轉換之後的範圍,則可能嚴重損失精度

實際上,Java提供了更爲便捷的數據類型自動轉換方式,例如byte x = 56,按照之前的知識,4個字節的int是無法自動轉換爲1個字節的byte的,但是隻要不超過byte的取值範圍-128~127,該賦值語句完全可以;但是byte x = 128則不合法,因爲128已經超出了byte的存儲範圍了

  • 更一般的規律是,當整數字面值不超過byte、short、char的取值範圍,這個字面值可以直接賦值給byte、short、char,這是Java追求更爲簡潔的語法
public class DataType{
    public static void main(String[] args){
        // int x = 100L; //大數轉小數報錯
        int x = (int) 100L; //加上(int)將100L強制轉換爲int,不會損失精度
        System.out.println(x);
        int y = (int) 2147483648L; //2147483648L已經超出待轉換類型的範圍,強制轉換會嚴重損失精度
        System.out.println(y);
        byte i = 56; //支持byte類型的範圍類大數轉小數
        System.out.println(i);
        //bytj j = 128; //超出byte類型報錯
        byte j = (byte) 128; //強制轉換嚴重損失精度
        System.out.println(j);
        char k = 32767; //不超過char的取值範圍,編譯通過
        char m = (char) 32768; //超過char的取值範圍,直接編譯失敗,強制轉換損失精度
        System.out.println(m);
    }
}

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-pysIYgmc-1589210639646)(evernotecid://7526024C-9E45-4F5B-9ACD-8B8C99291F7B/appyinxiangcom/20641877/ENResource/p1649)]

浮點型

  • 浮點型包括floatdouble,分別佔4個和8個字節,由於計算機內存有限,對於浮點型都是近似接近的。例如1/3=0.3333333333333…是無限循環小數,用有限的計算機內存資源存儲無限的數據只能是近似的
  • java對於所有浮點型字面值1.0會默認當作double,不能直接賦值給float類型,若想變成float可以通過:
    • 1.通過float強制類型轉換,可能會損失精度
    • 2.直接在字面值後加上F/f
  • 雖然double看似精度很高,但是對於財務領域依然不夠(動輒百億/千億的資金若因爲精度損失則會損失巨大),因此在java基礎SE類庫中,提供了更高精度的java.math.BigDecimal類庫幫助運算,只不過它們屬於引用的數據類型,不屬於基礎數據類型
  • 類庫是前人已經編寫好的專門處理某些特定領域問題的java代碼,java強大之處正是因爲可以基於這套龐大類庫開發。我們使用的String[] args實際上就是使用的String.class
    • SE類庫的字節碼一般位於類似jdk-version-x/lib/*.jar/*.class
    • SE類庫的源碼在類似jdk-version-x/src.zip中的.java源碼

布爾型

  • 布爾型boolean,在java中只有2個值true/false,不像其他語言可以用1/0表示,聲明一個布爾型boolean age = true
  • 布爾型主要是邏輯運算和條件判斷,例如:
public class Bool{
    public static void main(String[] args){
        boolean age = false; //聲明一個boolean類型false
        if(age){ 
            System.out.println("kids");//條件真則執行
        }else{ 
            System.out.println("adults");//條件假執行
        }
    }
}

類型轉換規則

  • 除了boolean,其他7種類型之間都可以相互轉換
  • 小數類型轉大數類型時是自動轉換,從小到到排序爲:
    byte < short/char < int < long < float < double
    注意:任何浮點類型都比長整型還大;shortchar雖然都是2個字節,但是char可以取更大的正整數
  • 大數轉小數的時候需要使用強制轉換符,並且在運行的時候可能會損失精度,需謹慎使用
  • 當整數字面值沒有超出byte/short/char取值範圍時,可以直接賦值
  • byte/short/char混合運算時,先各自轉換成int再運算
  • 多種類型運算時先轉換成最大類型再運算

參考

B站動力節點老杜老師的Java教程(原視頻戳這裏)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章