Java零基礎(chǔ)快速入門|數(shù)據(jù)類型(上)

本文章主要內(nèi)容:
數(shù)據(jù)類型概述
字符編碼
字符型詳解
整數(shù)型詳解
學習目標
帶大家理解數(shù)據(jù)類型的作用,八種基本數(shù)據(jù)類型各是什么,常見數(shù)據(jù)類型的取值范圍,怎么使用它們聲明變量,各數(shù)據(jù)類型使用時的注意事項,另外要知道在實際開發(fā)中怎么選擇合適的數(shù)據(jù)類型,還有這八種基本數(shù)據(jù)類型之間的相互轉(zhuǎn)換。
知識框架

數(shù)據(jù)類型概述
在上一篇文章中我們學習了變量,我們知道任何一個變量都包括三要素,分別是:數(shù)據(jù)類型、變量名、值。其中數(shù)據(jù)類型尤為重要,目前我們已經(jīng)接觸過一種數(shù)據(jù)類型,那就是表示整數(shù)型 的int。接下來我們一起來學習一下其他的數(shù)據(jù)類型。
在學習其他數(shù)據(jù)類型之前我們先來思考一個問題,數(shù)據(jù)類型在程序中起到什么作用呢?
實際上是這樣的,軟件的存在主要是進行數(shù)據(jù)的處理,現(xiàn)實生活中的數(shù)據(jù)有很多,所以編程語言 對其進行了分門別類,然后就產(chǎn)生了數(shù)據(jù)類型,不同數(shù)據(jù)類型的數(shù)據(jù)會給其分配不同大小的空 間進行存儲。也就是說,數(shù)據(jù)類型作用就是決定程序運行階段給該變量分配多大的內(nèi)存空間。這就是數(shù)據(jù)類型的主要作用。
那么java中的數(shù)據(jù)類型都包括哪些呢?實際上Java中的數(shù)據(jù)類型就包括兩大類:
基本數(shù)據(jù)類型
引用數(shù)據(jù)類型
?其中,基本數(shù)據(jù)類型又包括 4 類 8 種:
第 1?類:整數(shù)型(不帶小數(shù)的數(shù)字):byte,short,int,long
第 2?類:浮點型(帶小數(shù)的數(shù)字):float,double
第 3?類:字符型(文字,單個字符):char
第 4?類:布爾型(真和假):boolean
大家可以看到,在以上的基本數(shù)據(jù)類型范疇中未發(fā)現(xiàn)字符串類型(帶雙引號的是字符串), 所以,在這里我要告訴大家,Java 中的字符串屬于引用數(shù)據(jù)類型,不屬于基本數(shù)據(jù)類型的范疇。
通過以上的學習,我們知道八種基本數(shù)據(jù)類型指的是:byte、short、int、long、float、double、boolean、char。
接下來我們來看一下八種基本數(shù)據(jù)類型的詳細信息,請看下表:

通過上表我們可以看出八種基本數(shù)據(jù)類型中
byte?占用 1 個字節(jié)
short 占用 2 個字節(jié)
int 占用 4 個字節(jié)
long 占用 8 個字節(jié)
float 占用 4 個字節(jié)
double 占用 8 個字節(jié)
boolean 占用1?個字節(jié)
char?占用 2?個字節(jié)
那么字節(jié)是什么呢,這個大家要知道 1?個字節(jié)是8?個比特位, 那么又有同學問了,1?個比特位是什么,1?個比特位就是一個 1?或 0,或者說 1?個比特位就是一個二進制位。也就是說1?個字節(jié)是由8?個 1?和 0?組成的二進制數(shù)字串。
接下來我們先普及一下計算機基礎(chǔ)知識吧,實際上計算機在任何情況下都只能識別二進制,什么是二進制呢?
計算機畢竟是一臺通電的機器,電流只有正極、負極,所以只能表示兩種情況,也就是 1 和 0。對于一串由 1 和 0 組成的數(shù)字來說就是二進制,所謂的二進制就是滿2?進 1,請看以下十進制和二進制的對照表:

其實十進制和二進制之間是存在轉(zhuǎn)換規(guī)則的,如下所示:
十進制轉(zhuǎn)換成二進制:比方說十進制數(shù) 65?轉(zhuǎn)換成二進制,我們可以使用短除法,65 對 2?整除商32?余數(shù)為1,把 1?寫在旁邊,接著 32?對 2?整除商 16?余數(shù)為 0,把 0?寫在旁邊,用16?整除 2?商 0?余數(shù)為 0,把0?寫在旁邊,這樣進行下去直至商為0?時為止。然后把余數(shù)逆序排列就得到了 65?的二進制。如下圖所示:

二進制轉(zhuǎn)換成十進制:比方說二進制代碼為 1000001 的十進制數(shù)是多少呢?可以采用按權(quán)相加的方法,對于二進制代碼 1000001?首先從右邊第一位起對應 2?的零次方,第二位對應 2?的 1?次方,以此類推,把相應的數(shù)位與權(quán)值相乘得到的積相加即可,即 1×20+0×21+0×22+0×23+0×24+0×25+1×26=65
好了,計算機二進制的小插曲我們就先說到這里,言歸正傳,接下來我們繼續(xù)學習八種基本數(shù)據(jù)類型。
當我們對二進制有一定的了解之后,來看一下 byte ?類型的取值范圍,為什么最大值只能取到 127 呢:
首先數(shù)字是有正負之分,在二進制位當中最左邊的二進制位是符號位,0 表示正數(shù), 1 表示負數(shù),byte 屬于字節(jié)型,占用空間大小是 1 個字節(jié),1 個字節(jié)是 8 個 bit 位,所以 byte 類型最大值是左邊一個 0 右邊七個 1:01111111,這個二進制位實際上是 27-1,也就是 127。byte 類型最小值是-128,那么,這也說明 1 個字節(jié)最多可以表示 256 種不同的情況(-128 到127,中間有一個 0,共 256 個不同的數(shù)字)。
接下來我再給大家普及一下計算機的容量單位換算:
1byte = 8bit(1 個字節(jié)是 8 個比特位)
1KB = 1024byte 1MB =?1024KB
1GB =?1024MB
1TB ?=?1024GB
到這里,我相信各位會去想,我自己的硬盤是多大空間,可以存儲多少個二進制位,你可以算算哦!
對于以上的八種基本數(shù)據(jù)類型,其中 byte、short、int、long?屬于整數(shù)型,代表現(xiàn)實世界中的整數(shù),只不過容量大小不同,細分的話,byte?叫做字節(jié)型,short?叫做短整型,int?叫做整型, long?叫做長整型,在實際的開發(fā)中,為了兼顧到開發(fā)效率,選擇數(shù)據(jù)類型的時候也不會太斤斤計較,這四種類型中int 最為常用。
通過本小節(jié)的學習,大家需要知道八種基本數(shù)據(jù)類型分別包括哪些,每種類型占用幾個字節(jié),取值范圍是怎樣的。對于二進制和十進制的轉(zhuǎn)換,大家作為一個了解即可。
?
字符編碼
對于以上的八種基本數(shù)據(jù)類型來說,其中七種類型 byte,short,int,long,float,double,boolean 計算機表示起來是很容易的,因為這七種類型底層直接就是數(shù)字,十進制的數(shù)字和二進制之間有固定的轉(zhuǎn)換規(guī)則,所以計算機可直接表示和處理。
但是大家別忘了,除了以上的七種數(shù)據(jù)類型之外,還有一種類型叫做字符型 char,這個對于計算機來說表示起來就不是那么容易了,因為字符畢竟是現(xiàn)實世界當中的文字,而文字每個國家又是不同的,計算機是如何表示文字的呢?
實際上,起初的時候計算機只支持數(shù)字,因為計算機最初就是為了科學計算,隨著計算機的發(fā)展,為了讓計算機起到更大的作用,因此我們需要讓計算機支持現(xiàn)實世界當中的文字,一些標準制定的協(xié)會就制定了字符編碼(字符集),字符編碼其實就是一張對照表,在這個對照表上描述了某個文字與二進制之間的對應關(guān)系。
最初的時候美國標準協(xié)會制定了ASCII?碼,ASCII(American?Standard?Code?for?Information Interchange:美國信息交換標準代碼)是基于拉丁字母的一套電腦編碼系統(tǒng),主要用于顯示現(xiàn)代英語和其他西歐語言。它是現(xiàn)今最通用的信息交換標準,并等同于國際標準ISO/IEC?646。
ASCII?碼采用 1?個字節(jié)編碼,1?個字節(jié)可以表示256?種不同的形式(前面說過了),對于英文來說這個足夠了,因為英文單詞就是由 26個英文字母拼湊而成,大小寫全部才52個,再加上數(shù)字和標點符號也不會超過256個。但 ASCII?碼對于中文來說那就不夠了,因為漢字不止256個。
常見的 ASCII 碼需要大家能夠記住幾個,在 ASCII 碼中規(guī)定'a'對應 97,'b'對應 98,以此類推,'A'對應 65,'B'對應 66,以此類推,'0'字符對應48,'1'字符對應 49,以此類推,這些常見的編碼還是需要大家記住的。
在字符編碼當中,有這樣兩個常見的術(shù)語需要大家了解一下:編碼和解碼,它們都是什么, 我們拿字符'a'來解釋一下:'a'是 97,97 對應的二進制是01100001,那么從'a'到二進制01100001 的轉(zhuǎn)換過程稱為編碼,從二進制 01100001???到'a'的轉(zhuǎn)換過程稱為解碼。大家一定要注意:編碼和解碼要采用同一種字符編碼方式(要采用同一個對照表),不然會出現(xiàn)亂碼。這也是亂碼出 現(xiàn)的本質(zhì)原因。
隨著計算機的不斷發(fā)展,為了讓計算機支持更多國家的語言,國際標準組織又制定了ISO-8859-1 字符集,又被稱為latin-1,向上兼容 ASCII 碼,仍不支持中文,主要支持西歐語言。再后來,計算機慢慢的開始支持簡體中文、繁體中文、日本語、朝鮮語等,其中支持簡體中文 的字符集包括:GB2312 、GBK 、GB18030,它們的容量大小不同,其中GB2312?< GBK?< GB18030。支持繁體中文的是大五碼 Big5 等。后來,在上世紀90 年代初,國際組織制定了一種字符編碼方式,叫做 Unicode ?編碼,這種編碼方式統(tǒng)一了全球所有國家的文字,具體的實現(xiàn)包括:UTF-8,UTF-16,UTF-32 等。
Java 為了國際化,為了支持所有國家的語言,所以Java 采用的編碼方式為Unicode 編碼。例如字符'中'對應的 Unicode 碼是'\u4e2d'。在實際開發(fā)中幾乎所有的團隊都會使用 Unicode??編碼方式,因為這種方式更通用,兼容性更好。
通過本小節(jié)的學習,大家需要理解字符編碼是什么,有什么作用,常見的 ASCII 碼要知道一些,另外要理解什么是編碼,什么是解碼,要知道編碼和解碼采用的字符編碼方式不同時會出現(xiàn)亂碼,還要知道國際通用的編碼方式為 ISO-8859-1 ,支持簡體中文的編碼方式包括GB2312、GBK、GB18030,而 Java 采用 unicode 編碼,目前在實際的開發(fā)中大部分團隊都會選擇UTF-8 的編碼方式。
?
數(shù)據(jù)類型詳解
以上我們對數(shù)據(jù)類型有初步的了解之后,我們來詳細的學習一下每一種數(shù)據(jù)類型。
字符型詳解
字符型char 在 Java 語言中占用 2 個字節(jié),char?類型的字面量必須使用半角的單引號括起來,取值范圍為[0-65535],char 和short 都占用 2 個字節(jié),但是char 可以取到更大的正整數(shù), 因為char 類型沒有負數(shù)。
Java 語言中的char 類型變量可以容納一個漢字。請看以下程序:

我們對以上的程序編譯并運行,請看下圖結(jié)果:

我們可以看到Java 中的char 類型確實可以存儲一個漢字。我們再來看以下程序,假設(shè)字符我們采用雙引號括起來會怎樣:

我們對以上的程序進行編譯,請看下圖編譯結(jié)果:

我們看到編譯器報錯了,并且提示的錯誤信息是“不兼容的類型”,這是因為雙引號括起來不是char?類型,而是 String 類型,其實 String 類型就是Java 中的字符串類型,但大家要知道字符串不屬于基本數(shù)據(jù)類型,而是引用數(shù)據(jù)類型。所以類型不兼容。接下來我們來測試一下兩個或多個字符是否可以使用單引號括起來,請看以下代碼:

我們對以上的程序進行編譯,請看下圖編譯結(jié)果:

我們可以看出,編譯器報錯了,錯誤信息是“未結(jié)束的字符文字”,這是因為Java 中有規(guī)定,字符型只能是單個字符,當編譯器檢測到'ab'的時候,左邊以單引號開始,繼續(xù)檢測到a ?字符,然后編譯器會繼續(xù)檢查下一個字符是否為另一半單引號,結(jié)果不是,而是b,所以編譯器報錯了。這也說明了Java 中的字符只能是單個字符,不能是多個字符。
接下來,我們再來看一看關(guān)于轉(zhuǎn)義字符,轉(zhuǎn)義字符指用一些普通的字符組合代表一些特殊 的字符,由于組合用的字符改變了原意,稱為轉(zhuǎn)義字符。
Java 中的轉(zhuǎn)義字符以 \??開始,常見的轉(zhuǎn)義字符有:\t、\n、\u、\\、\',\",其中:
\t 代表制表符
\n 是換行符
\\表示一個普通的\字符
\'表示一個普通的'
\"表示一個普通的"
請看以下代碼:

我們對以上的程序進行編譯并運行,請看下圖結(jié)果:

對于以上程序,表面看起來'\t'是由兩個字符構(gòu)成,按說應該編譯報錯,因為它畢竟是兩個 字符組成的字符串,可是最終的結(jié)果編譯通過了,并且正常運行了,這說明了'\t'表示1 個字符, 所以\具有轉(zhuǎn)義功能,根據(jù)以上輸出結(jié)果可以看出\t??是制表符(abc 和 def 之間的空白就是制表符)。
接下來我們來看一看其它的轉(zhuǎn)義字符。請看以下程序:

我們對以上的程序進行編譯并運行,請看下圖運行結(jié)果:

通過以上代碼的測試,hello 和world 之間換行了,所以\n 代表一個換行符。
對于以上代碼的第 4?行 '\'' 來說,這里的 \?是不能去掉的,如果去掉之后代碼就變成了''', 那么此時編譯器會報錯,因為單引號'在 Java??中有特殊含義,在這個'''代碼當中第一個單引號' 會主動和第二個單引號'配對,此時最后的單引號'就是多余的了,不符合Java??的語法,所以會導致編譯錯誤,如果這個時候在第二個單引號'前面添加 \??進行轉(zhuǎn)義,代碼是'\'',那么此時第二個單引號 \' ?就是一個不具備特殊含義的普通單引號字符,這個時候第一個單引號'會和最后一個單引號'配對。編譯和運行就正常了。
對于以上代碼第 6?行來說和第 4?行的原理是相同的,代碼 \" ?表示普通的雙引號字符。對于第 5?行代碼來說,代碼 \\??聯(lián)合起來表示一個普通的 \??字符,在 Java?中 1?個 \??字符
不是普通的 \??字符,具有特殊的作用就是轉(zhuǎn)義,我們想讓其變成一個普通的 \??字符需要使用
兩個 \ 來表示,代碼 \\ 中,第一個 \ 具有轉(zhuǎn)義功能,第一個 \??將第二個 \??轉(zhuǎn)換成普通的 \??字符,以此類推,如果代碼是 \\\\ 這樣,則表示結(jié)果是 \\。
對于第 7 行代碼來說,如果代碼修改為'u4e2d'必然報錯,因為 u4e2d 在這個時候是一個普通的字符串,字符串是不能使用單引號括起來的,如果在 u?字符前添加轉(zhuǎn)義字符 \ 則表示的含義就不同了,\u 轉(zhuǎn)義之后表示后面的 4e2d 是一個unicode 碼,根據(jù) unicode 字符集可以查詢到漢字'中'的unicode 碼就是 4e2d,所以最終輸出結(jié)果是漢字'中'。
綜上所述,\n 表示換行符,\'表示普通的單引號字符,\\表示一個普通的\字符,\"表示一個普通的雙引號字符,\u 后面的十六進制是文字的unicode 編碼。
通過本小節(jié)的學習,我們需要掌握的是,在 Java 語言中,字符 char 類型的數(shù)據(jù)只能使用單引號括起來,并且在Java 語言中char 類型完全可以存儲一個漢字,另外還需要知道在Java 語言中 \ 具有轉(zhuǎn)義功能,常見的轉(zhuǎn)義字符要知道代表什么含義。
最后再給大家留兩行代碼,思考一下它的運行結(jié)果,在后面我們再詳細講解該內(nèi)容,請看以下代碼:

我們對以上的程序進行編譯并運行,請看下圖運行結(jié)果:

在這里我簡單提示一下,以上程序中的“+”運算符起到的作用是求和并不是字符串連接運算,剩下的大家思考一下吧,后面我們再看。
?
整數(shù)型詳解
整數(shù)型數(shù)據(jù)在java 中有 4 種表示方式,分別是十進制、八進制、十六進制、二進制。不過要注意的是二進制寫法是在Java7 中引入的,對于Java7 之前的版本不支持該語法。默認為十進制,以0?開始表示八進制,以0x 開始表示十六進制,以 0b 開始表示二進制。
十進制、八進制、十六進制有什么區(qū)別,請看:
十進制:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17...
八進制:0,1,2,3,4,5,6,7,10,11,12,13,14,15,16,17,20,21...
十六進制:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11...
接下來我們在代碼中試驗一下以上的幾種寫法,請看以下代碼:

我們對以上的程序進行編譯并運行,請看下圖運行結(jié)果:

通過測試確實可以看到八進制10 是 8,十六進制的10 是 16,二進制的 10 是2。在實際的開發(fā)中大部分還是直接使用十進制的方式,因為十進制對于我們來說更直觀,程序的可讀性會更好一些。
在 java?語言當中,整數(shù)型字面量被當做 int 類型處理,也就是說在程序中只要遇到整數(shù)型的數(shù)字,該數(shù)字會默認被當做 int 類型來處理,如果想表示 long 類型則需要在字面量后面添加L/l,建議大寫L,因為小寫l 和 1 不好區(qū)分。請看以下程序:

在以上的代碼中int a = 10;表示聲明一個int 類型的變量a,然后給a 變量賦值10,其中 10 是一個整數(shù)型字面值,根據(jù)以上規(guī)則,10 默認被當做int 類型來處理,那么int a = 10;就表示int 類型的字面量 10 賦值給int 類型的變量a,這個過程是不存在類型轉(zhuǎn)換的。
另外在以上代碼中long b?= 10L;表示聲明一個long 類型的變量b,然后給 b 變量賦值 10L, 由于 10 后面添加有L,則編譯器會將 10L 當做long 類型來處理,long 類型的字面量 10L 賦值給long 類型的變量b,這個過程也是不存在類型轉(zhuǎn)換的。
接下來我們在以上代碼的基礎(chǔ)之上繼續(xù)編寫,請看以下代碼:

我們可以看到在第 5 行新增了一行代碼:long c = 10;,這行代碼是什么原理呢?我們先來編譯,看看是否符合Java 的語法規(guī)則,請看下圖編譯結(jié)果:

接下來我們再運行一下,請看下圖運行結(jié)果:

通過以上的測試我們可以看到long c?= 10;這種編寫方式符合語法規(guī)則,并且也可以正常運行,我們來分析一下,10 是整數(shù)型字面量,按照以上規(guī)則,Java 中會將 10 默認當做int 類型處理,而c?變量是long 類型,int?類型可以賦值給long 類型的變量嗎?
答案是可以的,因為我們已經(jīng)測試過了。這是因為int 占用4 個字節(jié),而long 占用 8 個字節(jié),在Java 中小容量可以直接賦值給大容量,這個過程被稱為自動類型轉(zhuǎn)換。
接下來我們對以上代碼繼續(xù)編寫,請看以下代碼:

我們可以看到在第 7 行新增了一行代碼:int d?= c;,我們先對以上代碼進行編譯,請看以下編譯結(jié)果:

我們可以看到編譯器報錯了,也就是以上編寫方式不符合 Java?語法規(guī)則,我們來看一看為什么,首先我們看到錯誤提示信息是:不兼容的類型,從long?轉(zhuǎn)換到int?可能會有損失。
這是因為c?變量是long?類型占用8?個字節(jié),而負責接收的 d?變量是int?類型占用 4?個字節(jié),很明顯是大容量轉(zhuǎn)換成小容量,好比一大玻璃杯中的水倒向小玻璃杯,最終的結(jié)果可能會使水溢出, 因為小玻璃杯可能放不下。
編譯器檢測到這種情況的時候就不會自作主張了,需要程序員來指 定,因為數(shù)據(jù)的損失需要程序員知曉,畢竟數(shù)據(jù)損失是一件很嚴重的事情,而編譯器自身是不會負責的,于是Java中規(guī)定大容量如果需要轉(zhuǎn)換成小容量,則程序員必須手動添加強制類型轉(zhuǎn)換符才能編譯通過,這個過程我們稱為強制類型轉(zhuǎn)換。
我們對以上代碼進行修改,請看以下 修改之后的代碼:

我們可以看到將第 7 行的代碼修改為:int d?= (int)c;,這就是強制類型轉(zhuǎn)換,語法格式是在需要強轉(zhuǎn)的數(shù)據(jù)前添加小括號,小括號中寫上要轉(zhuǎn)換的類型,我們對以上的程序編譯并運行, 請看下圖結(jié)果:

通過以上的測試我們得出這樣一條結(jié)論:
一個數(shù)據(jù)在賦值給一個變量的時候存在三種不同的情況:
第一種情況是類型一致,不存在類型轉(zhuǎn)換;
第二種情況是小容量可以自動賦值給大容量,稱為自動類型轉(zhuǎn)換;
第三種情況是大容量不能直接賦值給小容量,大容量如果一定要賦值給小容量的話,必須添加強制類型轉(zhuǎn)換符進行強制類型轉(zhuǎn)換操作。
不過需要注意的是,強制類型轉(zhuǎn)換在使用的時候一定要謹慎,因為可能會導致精度損失,因為大杯水倒入小杯中,可能會導致水的溢出,不過這也不全都是,也可能精度不會損失,如果大杯中的水很少,這個時候倒入小杯中也可能是不溢出的。就像以上的運行結(jié)果,雖然進行了強制類型轉(zhuǎn)換,但并沒有損失精度。
接下來我們一起來看看精度損失是什么情況,請看以下代碼:

我們可以看到在以上代碼中,int 類型的變量 a 強轉(zhuǎn)為 byte 類型,我們對以上代碼進行編譯并運行,請看下圖運行結(jié)果:

4 個字節(jié)的int 類型300 強轉(zhuǎn)為1 個字節(jié)的byte 類型,最終的結(jié)果是44,為什么呢?這是因為首先int 類型的300 對應的二進制碼是:00000000 00000000 00000001?00101100,強制類
型轉(zhuǎn)換的時候會變成 1 個字節(jié),這個時候底層是將前 3 個字節(jié)砍掉了,也就是最后的二進制碼是:00101100,這個二進制碼對應的是 44。所以精度損失之后的結(jié)果就是44?了。
接下來我們再來看一下精度損失之后成為負數(shù)的情況,請看以下代碼:

我們對以上的代碼進行編譯和運行,請看下圖結(jié)果:

為什么以上的運行結(jié)果是-106呢?
這是因為計算機在任何情況下都是采用二進制補碼的形式存儲數(shù)據(jù)的(為什么采用二進制補碼形式存儲數(shù)據(jù),這里就不再贅述了,不做學術(shù)研究)。計算機二進制編碼方式包括原碼、反碼、補碼。對于正數(shù)來說原碼、反碼、補碼是同一個。
對于負數(shù)來說呢?負數(shù)的反碼是在其原碼的基礎(chǔ)上, 符號位不變,其余各個位取反,例如:-15 的原碼是:10001111,-15?反碼是:11110000。負數(shù)的補碼是其反碼再加1。例如:-15?的補碼是 11110000?加 1:11110001。換句話說-15?最終在計算機上會采用 11110001?二進制來表示。
我們再來看看以上的程序:int?a?=?150。4?個字節(jié)的150?對應的二進制是:00000000?00000000 00000000??10010110,強轉(zhuǎn)時前 3??個字節(jié)砍掉,最終計算機存儲的二進制為:10010110,我們之前說過最終存儲在計算機中的是二進制補碼形式,也就是說 10010110??現(xiàn)在是二進制補碼形式,我們通過補碼推出原碼,負數(shù)的補碼是反碼+1,所以10010110 減 1?就是反碼 10010101, 反碼的符號位不變,其余位取反就能得出原碼:11101010,而這個值就是-106。
對于以上原理 大家了解即可,在實際的開發(fā)中很少使用。
接下來我們再來看一段程序,分析以下程序錯在哪里,為什么以及怎么解決?

我們對以上的程序進行編譯,請看下圖結(jié)果:

我們可以看到,編譯報錯了,為什么呢?
原因是:java 程序見到 2147483648 這個整數(shù)的時候,默認將其當做int?類型來處理,但這個數(shù)字本身已經(jīng)超出了 int 類型的取值范圍(int 類型最大值是 2147483647),所以編譯報錯了
注意:這里編譯報錯的原因并不是說 long 類型存不下,long 類型的變量完全可以存儲這個數(shù)字,以上程序出現(xiàn)的錯誤是在賦值之前,還沒有進行到賦值運算,數(shù)字本身已經(jīng)超出 int 類型范圍,自己崩掉了。
怎么解決以上的問題呢?其實很簡單,我們只要讓 java 程序認為 2147483648 是一個long 類型的數(shù)據(jù)就行了,也就是說在該數(shù)字后面添加L 問題就解決了(long num?= 2147483648L;)。
接下來,一起來看一下以下程序是否可以編譯通過,請看代碼:

我們來分析一下以上的代碼:byte b?= 1;,1 是整數(shù)型字面量,在java 中默認被當做int 類型來處理,int 類型占用 4 個字節(jié),b 變量是 byte 類型占用 1 個字節(jié),根據(jù)上面所學,大容量無法直接賦值給小容量,要想賦值需要進行強制類型轉(zhuǎn)換,這里沒有強轉(zhuǎn),所以按理說編譯是報錯的,接下來我們來看一下編譯結(jié)果,請看下圖:

編譯結(jié)果讓我們意外了,編譯通過了,這是為什么呢?
我來給大家解釋一下,這是因為在java?語言有這樣一條規(guī)定,大家記住就行了,如果當一個整數(shù)型字面量沒有超出byte??類型取值范圍時,可以直接賦值給byte 類型變量。那么如果整數(shù)型字面量超出byte 類型取值范圍會怎樣呢?我們來測試一下,請看以下代碼:

我們對以上的代碼進行編譯,請看下圖編譯結(jié)果:

我們可以看到編譯報錯了,錯誤信息是第 7 行:不兼容的類型,從int 轉(zhuǎn)換到byte 可能會有損失。對于以上程序的第5 行并沒有報錯。針對這個錯誤信息我們之前在學習強制類型轉(zhuǎn)換的時候接觸過,也就是說以上程序要想編譯通過必須進行強制類型轉(zhuǎn)換,請看以下代碼:

我們對以上的程序進行編譯并運行,請看下圖結(jié)果:

我們通過測試結(jié)果可以看出程序正常編譯并運行了,這也印證了我們上面所說:當整數(shù)型字面量沒有超出byte 類型取值范圍時,可以直接賦值。不過,如果超出了byte 類型的取值范圍,在使用時必須進行強制類型轉(zhuǎn)換。但需要注意的是強制類型轉(zhuǎn)換會導致精度的損失,例如以上代碼中int?類型的 128 強轉(zhuǎn)為byte 之后結(jié)果是-128(這是因為計算機以二進制補碼形式存儲數(shù)字),還是要謹慎使用。
其實除了byte 類型有這樣的規(guī)則之外,short 和char 也具有同樣的規(guī)則,接下來我們先對
short 進行測試,代碼如下所示:

我們對以上的代碼進行編譯,請看下圖編譯結(jié)果:

通過以上的結(jié)果可以看出第 3 行代碼編譯通過了,但是第5?行編譯報錯了,這是因為 short 類型最大值是 32767。對于第 5 行的 32768 已經(jīng)超出了short 類型取值范圍,同樣如果要使用的話需要進行強制類型轉(zhuǎn)換,這里就不再演示了。
接下來我們再來看一看char 類型,char??同樣滿足以上規(guī)則,當沒有超出char 類型取值范圍時,可以直接賦值,請看以下代碼:

我們對以上的程序進行編譯并運行,請看下圖結(jié)果:

通過以上的測試可以看出當沒有超出char 類型取值范圍的時候,整數(shù)型字面量是可以直接賦值給char 類型變量的,但結(jié)果為什么會是字符a 和b 呢?
這是因為程序char c1?= 97;在實際執(zhí)行的時候存在隱式的類型轉(zhuǎn)換,會自動將int?轉(zhuǎn)換成char,由于 char 最終是一個字符,而97 正好是字符a 的ASCII 碼,所以最終結(jié)果是字符 a 和b。
那么如果超出char 類型取值范圍會怎樣呢(char 最大值是 65535)?請看以下代碼:

我們對以上代碼進行編譯,請看下圖編譯結(jié)果:

通過以上測試我們同樣看到一旦超出char 類型取值范圍時就不能直接賦值了,要修改以上的錯誤也是需要進行強制類型轉(zhuǎn)換操作,這里就不再演示了。
綜上所述,大家記住一個結(jié)論:當一個整數(shù)型的字面量沒有超出byte,short,char??的取值范圍,可以將該字面量直接賦值給byte,short,char 類型的變量,如果超出范圍則需要添加強制類型轉(zhuǎn)換符。
通過本小節(jié)的學習,我們需要掌握以下幾個內(nèi)容:
第一,Java??中的整數(shù)型字面量有四種表示方式,但最常用的還是十進制;
第二,整數(shù)型字面量被當做 int 處理,如果想當做 long 處理, 需要在后面添加L??或l;
第三,小容量轉(zhuǎn)換為大容量被稱為自動類型轉(zhuǎn)換;
第四,大容量轉(zhuǎn)換成小容量稱為強制類型轉(zhuǎn)換,強轉(zhuǎn)時需要添加強制類型轉(zhuǎn)換符,但要注意強轉(zhuǎn)可能損失精度;?
第五,當整數(shù)型字面量沒有超出byte、short、char 的取值范圍,可直接賦值。
最后附Java零基礎(chǔ)視頻教程給大家,配合學習效果更佳??!
