文章目錄
- 變數和型別
- 我們先來講講變數,
- 而變數的存盤空間從何而來?這里我們就要講講 記憶體
- 打個比方
- 切回實際
- 馮諾依曼體系 由五個部分組成
- 馮諾依曼體系結構圖
- 1,2這兩個部分就不用我解釋了(生活例子:鍵盤和螢屏),我們重點講講 外儲存器 和 記憶體儲器 有何區別?
- 舉個列子
- 電腦記憶體圖片示例(運行記憶體 RAM)
- CPU(運算器和控制器)
- 總結:
- 拓展
- JavaSE(Java Platform, Standard Edition - Java平臺標準版的簡稱) 中的 八大基本資料型別
- 1.整形變數( 4 byte)
- 基本語法格式
- 代碼示例
- 效果圖
- 整形變數的取值范圍
- 提醒:
- 例子
- 附圖
- 那么在 Java中 如何求 取值范圍的最大值和最小值?
- 在此之前,我們需要 integer 是什么?
- 程式例子:
- 效果圖
- 現在我們來在Java中求 int 型別 所能存盤最大值和最小值
- 最大值+1,最小值-1,會導致數值溢位(相當于碗就這么點大,容量有限,你非要裝,肯定是會溢位的),那么效果如何?
- Java有一個地方狠拐,,
- 注意事項
- 2.長整形變數(長整形:long 8 byte)
- 基本語法格式
- 注意 在Java中是沒有long long型別的,
- long 的取值范圍
- 程式如下:
- 注意事項
- 3 雙精度浮點型變數(8 byte)
- 基本語法
- 代碼示例
- 拓展代碼1
- 那么我么想得到 0.5,該怎么寫?
- 代碼如下
- 拓展代碼2
- 4 單精度浮點型變數(4 byte)
- 基本格式:
- 代碼示例
- 注意:
- 5 字符型別變數( 2 byte)
- 基本格式:
- 代碼示例
- 代碼2
- 注意事項:
- 6 位元組型別變數(相當于 C語言里面的char,記憶體大小 1 byte)
- 基本語法格式:
- 代碼如下:
- 附圖1
- 附圖2
- 附圖3(用 long 和 int 做比較)
- 另外 提示一下, 在Java當中,是沒有sizeof 這種運算子的,
- 注意事項:
- 7 短整型變數(2 byte)
- 基本語法格式
- 代碼示例
- 8 布爾型別變數
- 基本語法格式:
- 代碼示例:
- 附圖1
- 附圖2
- 附圖3
- 附圖4
- 注意事項:
- 至此Java的8大基本資料型別結束了,
- 下面我們來講講其他型別
- 字串型別變數
- 基本語法格式:
- 代碼示例:
- 知識點, String 是 字串型別,又稱 參考型別
- 在 Java 中 資料型別 主要分為 2部分:
- 拓展
- 圖6
- 圖7
- 圖8
- 圖 9
- 圖 10
- 轉義字符
- 程式實體
- 圖11
- 圖12
- 圖13
- 圖 14
- 圖15
- 變數的作用域
- 講到這里 我需要提醒一下的是
- 在 Java中 變數 分為兩種:
- 我們今天所講的 主要就是 區域變數的作用域
- 程式一
- 圖16
- 程式二
- 圖 17
- 接著上一個例子,那如果我這樣寫呢?
- 圖18
- 如何判斷變數的作用域?
- 變數的命名規則
- 硬性指標:
- 軟性指標:
- 程式1
- 圖19
- 程式2
- 圖20
- 常量
- 常量主要有以下兩種體現形式:
- 1.字面值常量
- 2. final 關鍵字修飾的常量
- 圖21
- 小知識點:
- 代碼示例
- 型別轉換
- int 和 long/double 相互賦值
- 圖22
- 那么 你說,我就想 把 b 的值 存入 a 里面,好的,沒問題,這就需要強制型別轉換
- 圖23
- 結論:
- int 和 boolean 相互賦值
- 圖24
- int字面值常量 給 byte 賦值
- 圖25
- 拓展
- 程式一
- 圖26
- 程式二
- 圖29
- 程式三
- 圖28
- 結論:
- 型別轉換小結
- 理解數值提升
- 程式實體
- 圖27
- 講到這里,有必要說一下 整形提升的意義何在?
- 型別提升小結:
- int 和 String 之間的相互轉換
- int 轉換 字串
- 圖30
- 圖31
- 字串轉換int
- 圖32
- 圖33
- 運算子
- 算術運算子
- +?? -?? ?* ?規則比較簡單, 注意的是除法
- 程式一
- 0 不能作為除數(重點)
- 圖35
- % 取余(求模/取模,說白了就是取余數)
- 圖36
- 圖37
- 來看一道題
- 圖38
- 增量賦值運算子(復合運算子) +=?? -=?? *=?? /=?? %=
- 圖39
- 圖40
- 圖41
- 自增/自減運算子 ++ --
- 后置加加
- 圖 42
- 前置加加
- 圖43
- 后置 減減
- 圖 44
- 前置減減
- 圖45
- 結論:
- 關系運算子(判斷資料)
- 圖46
- 拓展
- 在Java中,判斷條件是否成立,是根據布爾型別的
- 邏輯運算子
- 邏輯與 &&
- 規則: 兩個運算元都為 true, 結果為 true, 否則結果為 false
- 程式實體
- 圖 47
- 邏輯或 ||
- 規則: 兩個運算元都為 false, 結果為 false, 否則結果為 true
- 程式一
- 圖48
- 邏輯非 !
- 規則: 運算元為 true, 結果為 false; 運算元為 false, 結果為 true(這是個單目運算子, 只有一個運算元).
- 圖49
- 圖50
- 講到這里,我們看到了邏輯運算子存在著“短路”的情況,現在我們來了解一下 “短路求值”
- && 和 || 遵守短路求值的規則
- 這里值詳解 邏輯與,邏輯或 大家可以自己嘗試著思考
- 圖51
- 那上面的代碼這樣寫呢?
- 圖 52
- 結論
- 位運算子
- 按位與 &
- 結論
- 按位或 |
- 結論
- 注意!!!
- 按位異或 ^
- 依然是假設兩個數字 5 和 6
- 按位取反 ~
- 我這里寫一個 32 位 二進制數
- 注意:
- 小要求:需掌握 進制 之間轉換
- 移位運算
- 移位運算子有三個:
- 左移 <<
- 例子
- 右移 >>:
- 這里我就舉6
- 在假設一個 負數 -1
- 無符號右移 >>>
- 另外請記住 在Java中是沒有 無符號左移的,沒有意義
- 注意:
- 條件運算子
- 條件運算子只有一個:
- 舉個例子 求兩個數的最大值
- 圖53
- 運算子的優先級
- 程式一
- 圖 54
- 接著程式一, 如果你想算出 9,用小括號將 1 和 2 括起來
- 程式如下
- 圖 55
- 運算子之間是有優先級的. 具體的規則我們不必記憶. 只需要根據自己的邏輯加括號就可以
- 小結
- 本文在這里結束了,
變數和型別
變數 指的是 程式運行時 的 可變的量,相當于開辟一塊記憶體空間來保存一些資料
型別 則是 對 變數的種類 進行了 劃分,不同的型別 的 變數 具有不同特性
我們所討論的"變數"主要 和 我們的"記憶體"這樣的硬體設備密切相關
?
我們先來講講變數,
變數就像一個個大小不一的盒子(型別不同的變數),盒子的空間里面裝著不同的寶藏,
并且盒子里的寶藏是可以進行替換(覆寫) 的,只要放得下,如果放不下,咱就不要它,(Java是一門強勢語言,不存在截斷的情況,超出型別的取值范圍的值,強行存入,程式會報錯,并且程式從該處結束運行)
也就是說 不同型別的變數的空間 存盤的資料 都是不同的,且變數的值是可以改變的
?
而變數的存盤空間從何而來?這里我們就要講講 記憶體
打個比方
記憶體 就像 一個長長的街道,街道上住著形形色色的人(各種各樣的變數)
就好比 型別不同 值相同 且變數不同 的資料[兩個年紀相同的人,但是,是兩個人不是一個人,也不是一個家庭的成員 char a = 10;int b = 10;]
和 型別相同值不同 且變數不同 的資料(生在同一個家庭,有兄弟姐妹,他們獨特的存在, int a =10;int b =20;)
和 型別和值都相同 且變數不同 的資料(你可以認為就是一對雙胞胎,雖然他們出生一個家庭,同時出生,長得一模一樣,但確確實實是兩個人,int a=0;int b =0;)
和 型別和值都不同 且變數不同 的資料(你可以認為是兩個完全不搭邊的人,float a=3.14;int b = 5;)
變數 就好比 一個人的唯一性,是不可重復或分裂,在程式中一個變數是不可以被重復定義的,在現實生活中,你總不能說人會分身吧,
而且變數的存盤的資料 是可以被改變的,唯一不變的就是變數本身(int a;a就是變數本身),
人也是一樣的,可以改變自己的,為了成為更好的自己,一直在努力的各位,唯一不變的就是 我們還是自己,不可能變成另一個人,取代別人的存在(這個別杠,少看點劇)
只要是個人都有自己的家(變數都有自己的存盤空間),家是有門牌號的,而 門牌號 就相當于 變數存盤空間的地址
記憶體就好比是這一條街道所有人的資訊的匯總
?
切回實際
真正想要理解記憶體,需要理解 馮諾依曼 體系,因為現在的計算機都是以這個體系來建立我們邏輯關系的
小常識: 現代計算機之父 就是 約翰.馮.諾依曼,又是一個聰明絕頂之人’

馮諾依曼體系 由五個部分組成
1、輸入設備,2、輸出設備,3、外存盤器,4、記憶體儲器,5、運算器和控制器(兩者組成的,也就是所謂的CPU)
馮諾依曼體系結構圖

1,2這兩個部分就不用我解釋了(生活例子:鍵盤和螢屏),我們重點講講 外儲存器 和 記憶體儲器 有何區別?
舉個列子
買手機,商家可能會問你 你是要 8G+258G 還是 4G+64G 等等,

我們可以看到兩塊記憶體(小的記憶體,大的外存),我們都是 小一點的記憶體越大,玩游戲越順暢,后面大的那個記憶體,說明你可以存很多資料到手機里,如果你是258的,都不夠用,我想說汝分享否?
有的人會說,為什么我蘋果的記憶體(運行記憶體)沒有 安卓的大,玩同一個游戲,為什么它比我卡?
因為 蘋果手機的每一個部件都是為蘋果手機專門制造設計的,所以系統之間的兼容性很強,所以在玩游戲的時候,所占記憶體較小
而安卓機,就是一個組裝機,懂得都懂,一個手機可能有幾個廠家的部件組裝而成,所以兼容性不是很好,所以在玩游戲的時候,所占記憶體較大
說白了就是,蘋果房子的每一塊轉都是無縫鏈接,每一塊磚的大小形狀都是相同的,所以墻面光滑如玉(原裝就是強[貴])(打游戲,6的飛起),
而安卓房子,就像是每一個磚之間是存在間隔(系統不兼容,導致記憶體有所浪費),再加上每一塊磚的大小形狀有著一些或很大的差別(又會占用一些記憶體的空間),導致墻面不光滑(卡的飛起,成為甩鍋的物件)
當然國產機現在越做越好(貴)[好 == 貴].很好,我選小米
電腦記憶體圖片示例(運行記憶體 RAM)


?
CPU(運算器和控制器)
CPU當中 運算器(邏輯運算)和 控制器(控制程式的運行【怎么運行,從哪里運行】 和 停止 【停止的條件,停止】,停止之后又該怎么做?)
這里我們不做深究,我們只是在 了解 記憶體的程序中 了解一下 馮洛伊曼體系 ,其重點是記憶體儲器,也就是我們的記憶體,
總結:
變數 就是存盤在 記憶體(記憶體儲器【硬體】)當中,當變數的型別不一樣,存盤的資料也就不一樣,它所占記憶體大小就不一樣,
學了C的,都知道,變數在程式運行時,才在記憶體中申請空間,程式結束之后,要將空間還給 記憶體,
所以 變數的空間的創造和銷毀(回收),都與我們的記憶體儲器【硬體】有這密切的關系
這樣就回到我們的最初的標題注釋的內容,"變數"主要和我們的 "記憶體"這樣的硬體設備密切相關
?
拓展
變數的命名:
小駝峰形式 intMax,第一詞的首字符小寫,后面詞的首字符大寫(見附圖 駝峰)
在Java中 識別符號由數字、字母、下劃線、$,組成
表示開頭不能是數字( int a2;right, int 2a;error)
注意 $ 和 下劃線, 雖然可以這么寫 int $a,int _a, 但不建議(別給別人挖坑,保持良好代碼習慣),
舉個例子,有一個二貨這么寫 int ______a=0; ,你告訴我這有幾個下劃線?,所以別這么寫

?
JavaSE(Java Platform, Standard Edition - Java平臺標準版的簡稱) 中的 八大基本資料型別
1.整形變數( 4 byte)
基本語法格式
int 變數名 = 初始值;
代碼示例
public class DataTypeAndOperator{
public static void main(String[] args){
int num = 10;// 定義一個整形變數,變數就相當于有一個箱子是a,它的型別int,存盤的資料是 整數 10
/*
另外注意 在Java中,int 就是 4個位元組 的大小,與作業系統是多少位無關,這一點請牢記,
這是Java中的一個特點:可移植性強,就是 不管你的電腦是多少位作業系統,你把我的位元組碼檔案拿過去,都可以跑起來
*/
System.out.println(num);// (這里)直接放入你想要輸出列印的變數,就OK了,沒有像C一樣,有列印格式要求
// 如果還是像 C 一樣也可以,如下
System.out.printf("%d\n",num);
}//效果圖如下,在這里跟大家回顧上一篇博客的內容
java一共有三種列印方式
//System.out.println("列印換行,這種列印方式用的最多");
//System.out.print("列印不換行");
//System.out.printf("跟C語言一樣,以格式化的形式進行輸出,這種列印方式用的最少");
}
效果圖

?
整形變數的取值范圍
提醒:
在 Java中,是沒有無符號型別的(unsigned ),統一是 有符號的(signed ),就是 有符號數【正負數】,
也就意味著我們的數值轉化為二進制時,最高位永遠都是符號位
例子
int 為 4 byte,即 32 bit 位,即 32位 二進制數
(8 bit = 1 byte; 1024 byte = 1 kb; 1024 kb = 1mb; 1024 mb = 1gb; 1024 gb = 1 tb; 1024 tb = 1pb.)
最高位為符號位,那么剩下的31位,都是數值位,就是能表示出 2^31 個數字
最高位【符號位】為 0,表示為正,數值位全部取1,得到最大值 2^31-1,
因為0也算一個數字了,所以它能表達的最大值,就是 能表達數字的個數 減去一個1.(照理說是從1算起的,那么就是2^31),所以我們要減一(附圖)
最高位【符號位】為 1,表示為負,數值位全部全1,得到最小值【-2^31,這個就是從-1算起,所以是-2^31】(圖10)
附圖



?
那么在 Java中 如何求 取值范圍的最大值和最小值?
在此之前,我們需要 integer 是什么?
int是java提供的8種原始資料型別之一,Java為每個原始型別提供了封裝類,Integer是java為int提供的封裝類,
小知識點,
-
除了 int 和 char,的封裝類分別是 Integer,Character 之外
其它 6 個原始資料型別 都是首字符大寫(Byte、Short、Float、Double、Long、Boolean)
? -
八 個原始資料型別: byte(1)、 char(2)、short(2)、 int(4)、 float(4)、 double(8)、 long(8), 、boolean[布爾型別] (沒有明確規定它的大小,在JVM中 1位元組 或者 1 bit)
int的默認值為0,而Integer的默認值為null -
即Integer可以區分出未 未賦值 和 值為0 的區別,int則無法表達出未賦值的情況,例如,要想表達出 沒有參加考試 和 考試成績為0 的區別,則只能使用 Integer
-
另外,Integer提供了多個與整數相關的操作方法,例如,將一個字串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量,
程式例子:
int的默認值為0,而Integer的默認值為null,
public class DataTypeAndOperator{
public static void main(String[] args) {
int a;
System.out.println(a);
}
}
效果圖

程式出錯,不應該輸出為 0嗎?
因為在 Java中 一個區域變數,沒有進行初始化賦值,那么就不能夠使用它,如果運行,程式會報錯,
這里體現出 Java的安全性
ps:在Java中是沒有全域變數的,這點請記住
另外注意一點,在方法(main方法)中,定義的量叫做變數
在類的內部,方法的外部的變數,叫做屬性(又稱 成員變數),
比如說 我就在 DataTypeAndOperator 的花括號后面建立 int a 的變數
這時,a就是成員變數(屬性),它的默認值就是 0,
現在我們來在Java中求 int 型別 所能存盤最大值和最小值
public class DataTypeAndOperator{
public static void main(String[] args){
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}

上下兩者寫法師等價的,

最大值+1,最小值-1,會導致數值溢位(相當于碗就這么點大,容量有限,你非要裝,肯定是會溢位的),那么效果如何?
public class DataTypeAndOperator{
public static void main(String[] args){
System.out.println(Integer.MAX_VALUE+1);
System.out.println(Integer.MIN_VALUE-1);// 這里加減,沒有涉及到賦值,如果將其 賦值給int型別的變數,程式會報錯,停止運行
// 因為Java的安全性很高
}
}

從 效果圖 和 圓形圖 可以看出,正數 0~2^31-1,負數 -1 ~ -2^31.,-2 ^31 代替了 2^31的位置,從而形成了一個圓形范圍(取值回圈)
最大值加一,取得最小值;最小值減一,取得最大值
?
Java有一個地方狠拐,,
public class DataTypeAndOperator{
public static void main(String[] args) {
int 錢 = 10;
System.out.println(錢);
}
}

因為 Java 是Unicode字符集,它包含ASCII碼字符集,拉丁文,中文 等等…
所以 在 Java 中 能以中文作為變數,
但是最好不要這么寫,有點過了,,,
?
注意事項
- int 表示變數的型別是一個整形,另外 在 Java中 int 是沒有無符號型別的(unsigned int),統一是 有符號的int(signed int)
- 變數名是變數的標識(int a,a就是變數名),后續都是通過這個名字來使用變數
- Java 中 = 表示賦值,意思是給變數設定一個初始值,(和數學不一樣,數學里是等于的意思)
- 初始化操作時可選的,但是 建議 創建變數的時候都顯式初始化,(尤其是區域變數,不初始化,程式會報錯)
- 最后不要忘記分號,否則會編譯失敗
- // 表示注釋,注釋作為代碼的解釋說明部分,不參與編譯運行,
?
2.長整形變數(長整形:long 8 byte)
基本語法格式
long 變數名 = 初始值;
?
注意 在Java中是沒有long long型別的,
?
long 的取值范圍
long : 8 byte == 64 bit
除去一個符號位,還剩63位,也就是說 取值范圍為 -2^63 ~ 2^63-1
long型別的資料的最大值為 2^63-1,最小值為 -2^63
?
程式如下:
public class DataTypeAndOperator{
public static void main(String[] args) {
long a = 10l;// 10 后面加一個 大寫的 L ,表示long型別的資料,
// 如果是小寫 int a =10l,就不明顯,看起來 跟 數字 1 一模一樣,
代碼習慣!!!
// 所以 L 還是要大寫
long long b =10;// long long 型別是不存在的
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE);
}
}


注意事項
注意事項:
1. 基本語法格式和創建 int 變數基本一致, 只是把型別修改成 long
2. 初始化設定的值為 10L , 表示一個長整型的數字. 小寫的 l,不建議寫,
3. 使用 10 初始化也可以, 10 的型別是 int, 10L 的型別是 long, 使用 10 L 更好一些.
4. Java 中 long 型別占 8 個位元組. 表示的資料范圍 -2^63 -> 2^63-1
?
3 雙精度浮點型變數(8 byte)
基本語法
double 變數名 = 初始值;
代碼示例
public class DataTypeAndOperator{
public static void main(String[] args) {
double d = 10.1;
System.out.println(d);
}
}

拓展代碼1
public class DataTypeAndOperator{
public static void main(String[] args) {
int a =1;
int b =2;
System.out.println(a/b);
}
}

講道理 結果應該是0.5, 但是在Java中整數除以整數,結果只能是整數,
所以 結果取 0.5 整數位 0
?
那么我么想得到 0.5,該怎么寫?
代碼如下
public class DataTypeAndOperator{
public static void main(String[] args) {
double a =1.0;// 占 8個位元組
double b =2.0;
如果這樣寫呢?
// int a = 1.0;小數默認占8個位元組,int 肯定是 放不下的
// int b = 2.0;
System.out.println(a/b);
//只有 a 和 b都是小數的情況下,結果才是 我們想要的 0.5
}
}

?
拓展代碼2
public class DataTypeAndOperator{
public static void main(String[] args) {
double a =1.1;//小數 默認 占 8個位元組,而 double 也是 8 個位元組大小,所以放的下
double b =2.0;
System.out.println(a*a);
}
}

照理說 結果應該為 1.21
但是結果為 1.2100000000000002,后面多了一個 2,這是為什么呢?
因為在程式里,小數是沒有精確的數字的
也就是說 小數本身是沒有一個精確的數字的,它只能精確到幾位
// float型別,只能精確到小數點后 6 位
// double型別,只能精確到小數點后 16 位
?
4 單精度浮點型變數(4 byte)
基本格式:
float 變數名 =初始值;
代碼示例
public class DataTypeAndOperator{
public static void main(String[] args) {
float a =1.0f;// 占 4 個位元組
為什么不這樣寫?
//float a = 1.0;
因為小數是默認 占 8 位元組,也就是默認 double型別
你需要知道 Java是一門強勢語言,賦值一定要型別相同,否則代碼進行編譯時,是不會通過的,會報錯,
所以在 java 當中,對 單精度浮點型,也就是對float型別的變數,進行賦值時,小數后面一定要加上 小寫 f 或 大寫 F
12.5f 或 12.5F 這樣寫,就表明了 小數 12.5 是一個單精度浮點型資料,而非雙精度浮點型資料
System.out.println(a);
}
}


?
注意:
float 型別在 Java 中占四個位元組, 同樣遵守 IEEE 754 標準. 由于表示的資料精度范圍較小, 一般在工程上用到浮點數都
優先考慮 double, 不太推薦使用 float
?
5 字符型別變數( 2 byte)
基本格式:
char 變數名 = 初始值;
代碼示例
public class DataTypeAndOperator{
public static void main(String[] args) {
char a ='w';
char b = '強';
System.out.println(a);
System.out.println(b);
}
}

由效果圖可知 char 型別能夠存的下 漢字
一個漢字占 2 個位元組,也就意味著 char 在 Java 當中,所占記憶體大小為 2 位元組
?
代碼2
public class DataTypeAndOperator{
public static void main(String[] args) {
char a =97;// 97 是 字符 a 的 ASCII 碼值
System.out.println(a);
}
}

由圖可知 在 Java 中,將 整數 賦給char型別的變數,Java會將 整形資料 轉換成 ASCII碼值,再將其列印,其結果是 ASCII碼值 所對應的 字符
?
注意事項:
1. Java 中使用 單引號 + 單個字母 的形式表示字符字面值.
2. 計算機中的字符本質上是一個整數. 在 C 語言中使用 ASCII 表示字符
而 Java 中使用 Unicode 表示字符. 因此一個字符占用兩個位元組, 表示的字符種類更多, 包括中文.
?
6 位元組型別變數(相當于 C語言里面的char,記憶體大小 1 byte)
基本語法格式:
byte 變數名 = 初始值
代碼如下:
public class DataTypeAndOperator{
public static void main(String[] args) {
byte a =9;
另外 和 int 它們一樣,賦值超過它的取值范圍,程式會報錯
1 byte = 8 bit
除去符號位,取值范圍為 -2^7 ~ 2*7-1(-128~127)
byte b = 130;
System.out.println(b);// 附圖1
由圖可知,130 超出去 byte 能存盤的值,系統會認為該值的型別 是 其他型別,且所占位元組比它大,
兩者之間無法進行賦值
注意: 在Java中,所有資料,都是這樣,擁有屬于它們自己的取值范圍, 一個型別的變數,只能存盤該型別的取值范圍以內的值
超出了,我就存不了,
就是說 多一分不行,少一分可以,因為我放得下
型別 所占位元組大的,可以放下 比它 所占位元組要小的型別的值
就是說 一個型別的取值范圍比另一個型別的取值范圍 要大時, 取值范圍大的型別,可以存放 取值范圍小的型別的所有取值
說白了 就是 大吃小,小吃不下大,// 附圖3
System.out.println(a);// 附圖2
}
}
附圖1

附圖2

附圖3(用 long 和 int 做比較)

?
另外 提示一下, 在Java當中,是沒有sizeof 這種運算子的,
就是說 在 Java 中, 型別所占位元組的大小,你需要自己記住
?
注意事項:
1. 位元組型別表示的也是整數. 只占一個位元組, 表示范圍較小 ( -128 -> +127 )
2. 位元組型別 和 字符型別 互不相干 (不要混淆)
?
7 短整型變數(2 byte)
基本語法格式
short 變數名 = 初始值;
代碼示例
public class DataTypeAndOperator{
public static void main(String[] args) {
short a = 2;
2 位元組 == 16 byte
除去了符號位
它的取值范圍為 -2^15 ~ 2^15-1( -32768 ~ 32767)
System.out.println(a);
}
}

?
8 布爾型別變數
基本語法格式:
boolean 變數名 = 初始值;
代碼示例:
public class JavaFirst {
public static void main(String[] args) {
boolean flag = true;
System.out.println(flag);//附圖1
boolean flag3 = false;
System.out.println(flag3);// 附圖3
相信大家都是有一定的C語言基礎的
在 C語言中,0為假, 非零為真
那么我這么寫,
boolean flag2= 2;
這樣寫是不行的
在Java當中 boolean 型別,只有 2個取值
要么是 true,要么是 false
附圖2
我可以這樣寫嗎?
boolean flag5 = true +1;
boolean flag6 = false+1;
圖 4
}
}
附圖1

附圖2

那么 boolean 的值 只能為 ture 和 false
?
附圖3

附圖4

還有一個原因,true 和 false 根本就不是 一個數,所以根本無法相加
?
注意事項:
1. boolean 型別的變數只有兩種取值, true 表示真, false 表示假.
2. Java 的 boolean 型別和 int 不能相互轉換, 不存在 1 表示 true, 0 表示 false 這樣的用法.
3. boolean 型別有些 JVM 的實作是占 1 個位元組, 有些是占 1 個位元位, 這個沒有明確規定
假如
有一天 你碰到了一道題,有4個選項,讓你找出那個是對的(問布爾型別的大小)
你看其他三項是不是明確錯誤的(就是 一個選項 是 1 byte,其它的 都是 幾個位元組,那就選 1位元組的,懂吧)
至此Java的8大基本資料型別結束了,
?
下面我們來講講其他型別
字串型別變數
字串型別 是Java特有的型別,不屬于 8大基本資料型別,
字串 就是把 一些字符 放到一起,
基本語法格式:
String 變數名 = "初始值";
代碼示例:
public class JavaFirst {
public static void main(String[] args) {
String str = "hello";
System.out.println(str);// 效果見附圖
}
}

?
知識點, String 是 字串型別,又稱 參考型別
在 Java 中 資料型別 主要分為 2部分:
數值型別(基本資料型別) : 整數(byte、short、int、long)、浮點數(float、double)、字符(char)、布爾(boolean)
參考型別: String、陣列、類、介面、列舉
怎么判斷 一個變數 是不是 參考型別,你就看這個變數存盤的值,是不是一個地址
細品!! 提示一下 陣列名是什么? 嗯~~~
?
拓展
public class JavaFirst {
public static void main(String[] args) {
1
System.out.println("hello"+"world");// 圖 6
從效果圖可以看出 它們拼接成一個字串
也就是說 在 Java 中,兩個字串相加,就能拼接成一個字串,
即 + 號, 等于 拼接 命令
2
System.out.println("hello"+10+20);// 圖 7
由 結果得知, 字串和其它資料型別int 10 和 int 20,使用 + 拼接,其結果就是拼接成一個字串
語法格式:字串 + 其他資料型別(將其后的面的資料,不進行處理,轉換成字串,進行拼接)
3
System.out.println(10+20+"hello");// 圖 8
由結果得知, 其他型別資料int 30 和 字串,使用 + 拼接
雖然結果還是一個字串, 但 其他型別的資料,在拼接之前,就已經 處理過了,
4
System.out.println(10+""+20+"hello");// 圖 9
由結果得知, 當 一個 非字串型別int 10 與 "" ,使用 + 拼接時,會成為 一個字串(就相當于 10 帶上一個頭套)
那么 這就是 第二種情況( 字串"10" 和 其他型別資料(int 20) 拼接,其結果還是字串["1020"])
和 第一種情況(字串("1020")和 字串("hello") 拼接), 其結果 就是 "1020hello"
a = 10; b = 20(取巧)
System.out.println("a = " + 10 + "; b = " + 20);// 圖10
運用了 1 和 2 兩種情況
字串("a = ")和 其他型別資料 int 10 ,使用 + 號,進行拼接,使其成為一個字串 “a = 10”
字串("a = 10") 和 字串 ("; b = "),使其成為一個字串“a = 10; b = ”
字串("a=10; b=") 和 其他資料型別 int 20,使用 + 號,進行拼接,使其成為一個字串 "a = 10; b = 20"
}
}
圖6

?
圖7

圖8

圖 9

圖 10

?
注意事項:
1. Java 使用 雙引號 + 若干字符 的方式表示字串字面值.
2. 和上面的型別不同, String 不是基本型別, 而是參考型別(后面重點解釋).
3. 字串中的一些特定的不太方便直接表示的字符需要進行轉義.
?
轉義字符
| 轉義字符 | 釋義 |
|---|---|
| 1 ,??\ ? | 在書寫連續多個問號時使用,防止他們被決議成三字母詞 |
| 2,?? \ ’ | 用于表示字符常量’ |
| \“ | 用于表示一個字串內部的雙引號 |
| 3. ?? \ \ | 用于表示一個反斜杠,防止它被解釋為一個轉義序列符, |
| \a | 警告字符,蜂鳴 |
| \b | 退格符 |
| \f | 進制符 |
| \n | 換行 |
| \r | 回車 |
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \ddd | ddd表示1~3個八進制的數字, 如: \130 X |
| \xdd | dd表示2個十六進制數字, 如: \x30 0 |
注意!! 標有123的,轉義字符中間是沒有空格,因為我不給空格 它顯示不了 \ 的,
?
程式實體
public class JavaFirst{
public static void main(String[] args) {
String s1 = "bit";
System.out.println(s1);// bit
// 如果我想輸出 "bit",怎么寫
// String s2 = ""bit"";// "bit"? erorr,因為 編譯器會認為 兩個相鄰的發雙引號,先結合,將其當做一個整體,圖11
// 正確寫法
String s2 = " \"bit\" ";// 這里的 \ 就是轉義字符,使上式中,兩個相鄰的雙引號分離,成一個單獨雙引號
// 后面的斜杠也是一樣,使其分離成為一個單獨的雙引號,而這里分離出來的雙引號,與bit 結合("bit",注意這不是一個字串,你可以這雙引號,看作兩個單獨的字符),
// 最后剩下來的左右最外面的兩個雙引號,將其("bit")轉換成 字串 “ “bit” ”
System.out.println(s2);// 圖 12
// 如果我想輸出 \bit\
//String s3 = "\bit\"; // 結果與s2的錯誤寫法的一樣, 雙引號 與 \ 結合成一個整體,所以,idea編譯器 會提示 在 "\ 的后面缺少一個分號, 見圖 13
//正確寫法
String s3 = "\\bit\\";// 與s2同理,使兩個斜杠與雙引號分離,與bit先結合\bit\,最后外面的雙引號的作用,是將其(\bit\)當做一個字串存入 s3
System.out.println(s3);// 圖14
// 想輸出 \\bit\\,現在就很簡單了
String s4 = "\\\\bit\\\\";// 一個斜杠管一個字符(斜杠),這每邊有 4個斜杠, 所以每邊最后剩下 2個斜杠
// 最后剩下的兩個雙引號,將其(\\bit\\)當做一個字符存入 s4
System.out.println(s4);
// 圖 15
}
}
圖11

圖12

圖13

圖 14

圖15

?
變數的作用域
就是該變數能生效的范圍, 一般是變數定義所在的代碼塊(定義在大括號里
如果 該變數 出了(不在) 創建它的 大括號里,來到外道大括號外面,該變數就不能使用)
講到這里 我需要提醒一下的是
在 Java中 變數 分為兩種:
1.成員變數;普通成員變數,靜態成員變數(在后面講類和物件的時候,會重點講解)
2.區域變數
?
我們今天所講的 主要就是 區域變數的作用域
程式一
public class JavaFirst{
int b =0;
此時 b 就是成員變數,也就是說,在 類的里面,main方法的外面 定義的變數,稱為成員變數
public static void main(String[] args) {
int a = 10;// a 就是一個區域變數
}
public static void main2(String[] args) {
// 注意這 main2, 和 main 完全是兩碼事,我只是偷個懶,
// public static void func(String[] args) {} 這里 func 和 main2,就是通一個意思
System.out.println(a);
}
}
圖16

?
程式二
public class JavaFirst{
public static void main(String[] args) {
{// 請注意,這只是舉例子,這種寫法,是不被允許的,以后別寫這種代碼
int a =10;
}
System.out.println(a);
}
}
圖 17

這樣也不行,因為 區域變數 a 的作用域,只在創建它的大括號里能用,出了大括號就不能用
?
接著上一個例子,那如果我這樣寫呢?
public class JavaFirst{
public static void main(String[] args) {
int a =0;
{
a = 99;
}
System.out.println(a);
}
}
圖18

由圖可知,是可以輸出a 的值,且a的值為 99,這是因為 a == 99,和輸出陳述句,都在 區域變數 a 的作用域內(在創建區域變數a,所在的大括號里)
?
如何判斷變數的作用域?
去找 離該變數最近的大括號,該大括號所包含的范圍,就是 變數的作用域
?
變數的命名規則
硬性指標:
1. 一個變數名只能包含數字, 字母, 下劃線
2. 數字不能開頭.
3. 變數名對大小寫很敏感. 即 num 和 Num 是兩個不同的變數.
注意: 雖然語法上也允許使用中文/美元符($)命名變數, 但是 強烈 不推薦這樣做.</font>.
軟性指標:
1. 變數命名要具有描述性, 見名知意(英文).
2. 變數名不宜使用拼音(但是不絕對,最好別用就對了).
3. 變數名的詞性推薦使用名詞(英文).
4. 變數命名推薦 小駝峰命名法, 當一個變數名由多個單詞構成的時候, 除了第一個單詞之外, 其他單詞首字母都大
寫.
程式1
public class JavaFirst{
public static void main(String[] args) {
int 3a = 0;
int a3 = 0;
}
}
圖19

由圖可知 符合 變數的命名規則 硬性指標 第二條 不能以數字開頭
?
程式2
public class JavaFirst{
public static void main(String[] args) {
int Num = 1;
int num = 2;
System.out.println(Num);
System.out.println(num);
}
}
圖20

由結果得知 符合 變數命名規則 硬性指標 第三條 變數名對大小寫很敏感. 即 num 和 Num 是兩個不同的變數.
?
常量
每種型別的變數 也對應著 一種相同型別 的 常量.
常量 指的是運行時型別不能發生改變.
常量主要有以下兩種體現形式:
1.字面值常量
| 10 | int 字面值常量(十進制) |
|---|---|
| 010 | int 字面值常量(八進制) 由數字 0 開頭. 010 也就是十進制的 8 |
| 0x10 | int 字面值常量(十六進制) 由數字 0x 開頭. 0x10 也就是十進制的 16 |
| 10L | long 字面值常量. 也可以寫作 10l (小寫的l) |
| 1.0 | double 字面值常量. 也可以寫作 1.0d 或者 1.0D |
| 1.5e2 | double 字面值常量. 科學計數法表示. 相當于 1.5 * 10^2 |
| 1.0f | float 字面值常量, 也可以寫作 1.0F |
| true | boolen 字面值常量, 同樣的還有 false |
| ‘a’ | char 字面值常量, 單引號中只能有一個字符 |
| “abc” | String 字面值常量, 雙引號中可以有多個字符. |
?
2. final 關鍵字修飾的常量
public class JavaFirst{
public static void main(String[] args) {
int a = 10;// a 此時是一個變數
a = 99;//變數是可以改變的
System.out.println(a);
// 如果在前面加個一個 final
final int b = 10;// 是它具有常量屬性,不可被改變,這點跟C語言中的const 是一樣的功能
b = 20;
System.out.println(b);
}
}
圖21

由圖可知, b 現在就相當于是 整形常量,值是無法改變的(另外體現出:常量的值,只能初始化一次,不像變數可以重復賦值),
? 另外:
我建議常量識別符號 用大寫好一點,小寫也行,你可以認為這是一種默認代碼習慣
即:final int B = 10;
System.out.println(B);// 10
小知識點:
常量 在程式編譯時,就已經確定了其值是什么
代碼示例
public class JavaFirst{
public static void main(String[] args) {
int a =10;// a 是變數,是在程式運行時,才確定其值是什么
final int b =20; // b就是一個常量,它的值,在程式還沒有運行之前,在編譯階段就已經確定了其值是什么
意味著 常量 的 值 確定的速度非常快
有多快,比變數快(變數已經哭暈在廁所)
}
}
?
型別轉換
java 作為一個強型別編程語言, 當不同型別之間的變數相互賦值的時候, 會有教嚴格的校驗
int 和 long/double 相互賦值
public class JavaFirst{
public static void main(String[] args) {
int a =10;
long b =20;
a=b;// 編譯出錯,提示 數值精度可能有所損失
// 因為 long 8個位元組,int是 4個位元組,int 肯定是放不下long的
b=a;// 編譯通過
// 因為 long 8個位元組,int是 4個位元組,long肯定是放得下int的,
//有的人可能會說 我一個int型別,怎么可能放不下20,我int型別表示不服!
//但你們要明白,你知道,不代表編譯器知道,在程式執行之前,系統是不知道你輸入資料有多大的
// 所以 在Java中,Java為了提高代碼的安全性,只要是型別不匹配的值,所占位元組大的型別 是無法對 所占位元組小的型別,進行賦值的
// 而 所占位元組小的型別 是可以對 所占位元組大的型別進行賦值的,(就是所謂的 大吃小,小吃不下大)
// 統統在編譯時,不給予通過,程式報錯并結束運行,
(圖22)// 其實在編譯之前,它就提示你,一個型別所占位元組大的 和 另一型別所占位元組小的,大的無法對小的進行賦值
// 也就是說 不存在 值的大小 是否存的下,只看型別之間,誰吃誰,大吃小沒問題,小吃大,容易被撐死
// 這里又在一次體現出 Java 的安全性,也體現出Java是一門強勢語言,對型別的檢查非常嚴格
你程式還沒運行,就提示你有錯誤,你想出錯都難(注意 a = b 下面的紅色波浪線就是在提醒你的寫法出錯了)
}
}
圖22

?
那么 你說,我就想 把 b 的值 存入 a 里面,好的,沒問題,這就需要強制型別轉換
public class JavaFirst{
public static void main(String[] args) {
int a =10;
long b = 20;
a = (int)b;// 把 b 的型別強制型別轉換成 int,然后賦給a
// 相當于 一個人給你打包票,我做事沒問題!
System.out.println(a);//圖 23
}
}
圖23

結果得知,是可行的,
但是注意一點,任何強制型別轉換都是有風險的,你再牛逼也有翻車時候
?
結論:
不同 數字型別 的 變數 之間賦值, 表示 范圍更小的型別 能隱式轉換成 范圍較大的型別, 反之則不行.
?
int 和 boolean 相互賦值
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
boolean b = true;
b = a; // 編譯出錯, 提示不兼容的型別
a = b; // 編譯出錯, 提示不兼容的型別
// 因為 boolean 根本就不是一個數字或者說型別都不一樣,所以兩者根本就無法進行相互賦值
// 圖 24
}
}
圖24

結論: int 和 boolean 是毫不相干的兩種型別, 不能相互賦值
?
int字面值常量 給 byte 賦值
public class JavaFirst{
public static void main(String[] args) {
// 注意 byte 的取值范圍 -128 ~127
byte a = 100; // 編譯通過
// 只要超過 byte 的取值范圍,編譯器會將 賦給 byte變數的值 認為是另一個型別的值,且比 byte 所占位元組大小更大的型別
byte b = 256; // 編譯報錯, 提示 從int轉換到byte可能會有損失
}// 圖25
}
圖25

結論: 使用字面值常量賦值的時候, Java 會自動進行一些檢查校驗, 判定賦值是否合理
?
拓展
程式一
public class JavaFirst{
public static void main(String[] args) {
byte a = 10;
byte b = 20;
byte c = a+b;
這樣寫是錯的,
// 因為在CPU中,兩個型別的資料(型別小于4個位元組的資料)在進行運算時,會整形提升
// 也就是說 a 與 b,在進行加法運算時,發生整形提升,兩者變為了 int 型別的資料
// 其結果當然也是 int 型別,所以無法將其運算結果賦給 byte型別的 變數 c
}// 圖 26
}
圖26

?
程式二
public class JavaFirst{
public static void main(String[] args) {
byte a =10;
byte b =20;
byte c = 10+20;
System.out.println(c);
這樣寫沒錯,為什么?
// 因為在 CPU 看來,這就是 兩個常量相加,而不是兩個變數相加(就該程式而言:如果是兩個變數相加,就需要整形提升,其結果資料是int型別)
// CPU 將兩個常量相加的結果(30) 賦給 一個型別的變數(byte c)
}
}// 圖29
圖29

?
程式三
public class JavaFirst{
public static void main(String[] args) {
int a = 0;
double b = 10.5;
a = (int)b;
System.out.println(a);
}
}// 圖 28
圖28

?
結論:
使用 (型別) 的方式可以將 double 型別強制轉成 int. 但是
1. 強制型別轉換可能會導致精度丟失. 如剛才的例子中, 賦值之后, 10.5 就變成 10 了, 小數點后面的部分被忽略.
2. 強制型別轉換不是一定能成功, 互不相干的型別之間無法強轉
總得來說,只要是強制型別轉換,都存在一定風險,正如我上面所說的 你再牛逼也會翻車,
?
型別轉換小結
1. 不同 數字型別 的 變數之間賦值, 表示 范圍更小的型別 能隱式轉換成 范圍較大的型別
(這里不是整形提升,就是單純的 大吃小:數字型別 所占位元組小的變數,它的所有取值,都可以 存盤到 比它所占位元組更大 的 數字型別 變數 當中).
2. 如果需要把范圍大的型別賦值給范圍小的, 需要強制型別轉換, 但是可能精度丟失.
3. 將一個字面值常量進行賦值的時候, Java 會自動針對數字范圍進行檢查.
?
理解數值提升
程式實體
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
long b = 20;
int c = a+b;
這樣為什么會錯呢?
因為CPU中,做型別提升時,小的型別會向大的型別進行型別提升(大的型別 所占位元組 要大于4位元組,否則,提升為整形)
也就是說 a 與 b,在進行加法運算時,發生類形提升,兩者變為了 long 型別的資料
其結果當然也是 long 型別,所以無法將其運算結果賦給 int 型別的 變數 c
需要強制型別轉換才能存進去, int c = (int)(a+b);
}// 圖 27
}
圖27

?
講到這里,有必要說一下 整形提升的意義何在?
?
為了效率高!.
?
型別提升小結:
1. 不同型別的資料混合運算, 范圍小的會提升成范圍大的.
2.由于計算機的 CPU 通常是按照 4 個位元組為單位從記憶體中讀寫資料. 為了硬體上實作方便, 諸如 byte 和 short 這種低于
4 個位元組的型別, 會先提升成 int, 再參與計算
?
int 和 String 之間的相互轉換
int 轉換 字串
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
String ret = String.valueOf(a);// valueOf 小駝峰結構,第一個詞的首字母不大寫,后面的都大寫
// 這是Java當中,把 數字 轉換成 字串 的方法,
System.out.println(ret);
}
}// 圖30 31
圖30

圖31

?
字串轉換int
public class JavaFirst{
public static void main(String[] args) {
String ret = "123";
int i = Integer.valueOf(ret);// valueOf 小駝峰結構,第一個詞的首字母不大寫,后面的都大寫
// 這是Java當中,把字串轉換成數字的方法,C語言里面用的是 atoi 庫函式
System.out.println(i);
// 在這里再講一次
// java提供的8種原始資料型別之一,Java為每個原始型別提供了封裝類,Integer是java為int提供的封裝類
// Integer提供了多個與整數相關的操作方法,例如,將一個字串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量
// 簡單來使 Integer 是一個 類,是 int 的包裝類,類里面包含這很多與int相關功能,
}
}// 圖32 33
圖32

圖33

?
運算子
算術運算子
基本四則運算子 + - * / %
+?? -?? ?* ?規則比較簡單, 注意的是除法
程式一
public class JavaFirst{
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println(a / b);
}// 圖 34
}

結果為 0,為什么呢?不應該是 0.5嗎?
因為 兩個整數相除,其結果也是整數,
所以 取結果的整數為 0,作為最后結果,
?
0 不能作為除數(重點)
public class JavaFirst{
public static void main(String[] args) {
int a =1;
int b =0;
System.out.println(a/b);
}
}// 圖 35
圖35

該錯誤被稱為 例外錯誤(術語)
只要程式拋出 例外錯誤,程式在例外錯誤的位置,結束程式的運行
?
% 取余(求模/取模,說白了就是取余數)
public class JavaFirst{
public static void main(String[] args) {
System.out.println(10%3);
// 10 除 3 ,取余 肯定是 1,附圖36
//在 Java中 可以對 小數 求余
System.out.println(11.5 % 2);// 圖37
}
}
圖36

圖37

?
來看一道題
我賭你們有些人絕對會算錯下面取余的題
public class JavaFirst{
public static void main(String[] args) {
System.out.println(-10%3);
System.out.println(10%-3);
System.out.println(-10%-3);
// 結果見圖 38
}
}
?
圖38

?
增量賦值運算子(復合運算子) +=?? -=?? *=?? /=?? %=
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
a+=1;// 等價于 a = a + 1 == 10+1 == 11
System.out.println(a);
// 圖39
// 但是請注意
short s = 10;
s= s+1;// 這樣寫會出錯,因為涉及到運算,會進行整形提升,s(這里代表的是常量10,不是變數 s) 和 1 都為 int型別
// 其結果也是int型別,所以無法賦給 short型別變數 s
// 如果想要 將其結果,強制型別轉換
s = (short)(s+1);// 圖 40
//但是! 如果使用 符合運算子,奇跡再現
s += 1;// 圖 41
// 由圖可知這樣寫,沒有出錯,
// 因為復合運算子,自帶強制型別轉換
}
}
圖39

圖40

圖41

?
自增/自減運算子 ++ –
后置加加
public class JavaFirst{
public static void main(String[] args) {
int a =10;
int b = a++;// 先將a的值(10)賦給 b(b==10),然后自增加1,a == 11
System.out.println(a);
System.out.println(b);
}//圖42
}
圖 42

?
前置加加
public class JavaFirst{
public static void main(String[] args) {
int a =10;
int b = ++a;// a先自增加1,a == 11,再將其值賦給 b(b==11)
System.out.println(a);
System.out.println(b);
}//圖43
}
圖43

?
后置 減減
public class JavaFirst{
public static void main(String[] args) {
int a =10;
int b =a--;// 先將a的值 10 賦給 b(b=10),a再自減1 a == 9
System.out.println(a);
System.out.println(b);
}// 圖44
}
圖 44

?
前置減減
public class JavaFirst{
public static void main(String[] args) {
int a =10;
int b =--a;// a先自減1 a == 9,再將a的值 9 賦給 b(b=9),
System.out.println(a);
System.out.println(b);
}// 圖45
}
圖45

?
結論:
1. 如果不取自增運算的運算式的回傳值, 則前置自增和后置自增沒有區別.
2. 如果取運算式的回傳值, 則前置自增的回傳值是自增之后的值, 后置自增的回傳值是自增之前的值.
?
關系運算子(判斷資料)
關系運算子主要有六個:
== != < > <= >=
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
int b = 20;
//條件為真,回傳 true,否,則回傳 false
System.out.println(a == b);
System.out.println(a != b);
System.out.println(a < b);
System.out.println(a > b);
System.out.println(a <= b);
System.out.println(a >= b);
}
}//圖46,由結果得知,所有關系運算子的回傳值 都是布爾型別資料(true 和 false)
圖46

?
拓展
在Java中,判斷條件是否成立,是根據布爾型別的
public class JavaFirst{
public static void main(String[] args) {
if(true)//條件為真,執行if陳述句
{
;
}
if(false)// 條件為假,不執行if陳述句
{
;
}
//if(0) 和 if(1)// 這種寫法在Java是不存在的
}
}
?
邏輯運算子
邏輯運算子主要有三個:
&& || !
注意: 邏輯運算子的運算元(運算元往往是關系運算子的結果)和回傳值都是 boolean 型別的資料(true 和 false)
?
邏輯與 &&
規則: 兩個運算元都為 true, 結果為 true, 否則結果為 false
運算式1 && 運算式2,都為 true, 結果為 true, 否則結果為 false
而且 邏輯與 支持 短路
什么意思呢? 如果 運算式1 為 假,后面的運算式2就不執行了,因為沒必要
邏輯或: 雙true出true,有false出false
有一個false,整個運算式的結果就為 false,所以 運算式2 看與不看(執不執行)都沒多大的關系
?
程式實體
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
System.out.println(a < b && b < c);
// a確實小于b,b也確實小于 c
// 即 雙 true 出true
//所以輸出結果為 true
}// 圖 47
}
圖 47

?
邏輯或 ||
規則: 兩個運算元都為 false, 結果為 false, 否則結果為 true
也存在 短路現象
運算式1 || 運算式2
有 true 出 true,雙 false 出 false
只要運算式1 為真(true),整個運算式就為true,運算式2 就不用執行了,因為不影響結果
程式一
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
System.out.println(a < b || b < c);
// a 確實小于 b, a<b 為真(true),整個運算式為 true
// 運算式2(b<c) 就沒有被執行
}
}// 圖48
圖48

?
邏輯非 !
規則: 運算元為 true, 結果為 false; 運算元為 false, 結果為 true(這是個單目運算子, 只有一個運算元).
public class JavaFirst {
public static void main(String[] args) {
int a = 10;
int b = 20;
// System.out.println(!a<b);
// 由圖49可知,!后面跟著不是 boolean 型別的資料
// 所以這種寫法是錯誤的
// 如果是這樣寫,就沒錯
System.out.println(!(a<b));//圖50
//因為 所有關系運算子(我們這里是 < )的回傳值 都是布爾型別資料(true 和 false)
}
}
圖49

圖50

?
講到這里,我們看到了邏輯運算子存在著“短路”的情況,現在我們來了解一下 “短路求值”
&& 和 || 遵守短路求值的規則
System.out.println(10 > 20 && 10 / 0 == 0); // 列印 false
System.out.println(10 < 20 || 10 / 0 == 0); // 列印 true
這里值詳解 邏輯與,邏輯或 大家可以自己嘗試著思考
public class JavaFirst{
public static void main(String[] args) {
System.out.println(10>20 && 10/0 == 0);
// 大家注意,這個運算式是存在錯誤的
// 除數 是不能為 0的
// 那么運行的結果會是如何?
//圖 51
}
}
圖51

?
那上面的代碼這樣寫呢?
public class JavaFirst{
public static void main(String[] args) {
System.out.println(10<20 && 10/0 == 0);
// 與上不同,這里是小于號,10 確實小于20,所以為真
// 繼續執行程式
// 然后,它才能檢測到 除數 是不能為 0的
// 那么運行的結果可以想象
//圖 52
}
}
圖 52

?
結論
1. 對于 && , 如果左側運算式值為 false,則運算式的整體的值一定是 false, 無需計算右側運算式
2. 對于 ||, 如果左側運算式值為 true, 則運算式的整體的值一定是 true, 無需計算右側運算式
?
位運算子
Java 中對資料的操作的最小單位不是位元組, 而是二進制位(bit).
位運算子主要有四個:
& | ~ ^
位操作表示 按二進制位運算. 計算機中都是使用二進制來表示資料的(01構成的序列), 按位運算就是在按照二進制位的每一位依次進行計算.
?
按位與 &
直接舉例子
0000 1010
0000 1000 上下對應著看,如果兩個二進制位都是 1, 則結果為 1, 否則結果為 0
0000 1000
結論
一個數的二進制數 與 另一個數的二進制數,相對應的二進制位上的數字,都是1,則結果為1,否則為0
假設兩個數字 5 和 6,這里我們不寫太多,就寫 4個bit位,因為它們的數值都不是很大,就不浪費空間了
5 0101
6 0110
0100 其結果對應的十進制數為 4
?
按位或 |
如果兩個二進制位都是 0, 則結果為 0, 否則結果為 1
依然是假設兩個數字 5 和 6
5 0101
6 0110
0111 其結果對應的十進制數為 7
結論
一個數的二進制數 與 另一個數的二進制數,相對應的二進制位上的數字,都是0,則結果為0,否則為1
注意: 當 & 和 | 的運算元為整數(int, short, long, byte) 的時候, 表示按位運算, 當運算元為 boolean 的時候, 表示邏輯 運算.
?
注意!!!
&(按位與) 和 |(按位或) (不推薦使用,因為在Java當中使用的太少了,所以大家只需要了解一下就可以了)
& 和 | 如果運算元為 boolean 的時候, 也表示邏輯運算. 但是和 && 以及 || 相比, 它們不支持短路求值
System.out.println(10 > 20 & 10 / 0 == 0); // 程式拋出例外
System.out.println(10 < 20 | 10 / 0 == 0); // 程式拋出例外
不會有人這么奇怪的代碼的,大家也別寫!!!
?
按位異或 ^
如果兩個數字的二進制位相同, 則結果為 0, 相異則結果為 1
依然是假設兩個數字 5 和 6
5 0101
6 0110
0011 其結果對應的十進制數為 3
?
按位取反 ~
如果該位為 0 則轉為 1, 如果該位為 1 則轉為 0
我這里寫一個 32 位 二進制數
-1的補碼
1111 1111 1111 1111 1111 1111 1111 1111
進行按位取反
0000 0000 0000 0000 0000 0000 0000 0000
由結果得知:按位取反,是 數值位 和 連符號位一起取反,這一點需要注意
?
注意:
1. 0x 前綴的數字為 十六進制 數字. 十六進制可以看成是二進制的簡化表示方式. 一個十六進制數字對應 4 個二進制位.
2. 十六進制的f 表示 10 進制的 15, 也就是二進制的 1111
3. printf 能夠格式化輸出內容, %x 表示按照十六進制輸出.
4. \n 表示換行符
小要求:需掌握 進制 之間轉換
這個不講,真要講的話,我的習慣可能寫的非常細,再加上將每個進制轉換都講清楚的話,感覺要寫一篇 接近 萬字的博客
你們自行了解,我就不再增長本文章的長度了
?
移位運算
移位運算子有三個:
<< >> >>>
都是按照二進制位來運算
另外 整數在記憶體中存的是補碼,詳細看這篇文章0operator(運算子)- 重置版,C語言和Java 這方面是一樣的
?
左移 <<
最左側的二進制位不要了,最右邊補一個零
例子
依然是 5 ,只不過這次是 32位,方便你們理解
0000 0000 0000 0000 0000 0000 0000 0101 (5)
5 << 1,5的二進制位 左移1位
0000 0000 0000 0000 0000 0000 0000 101 (最左側的零其實已經擠掉了,由于整個二進制數向左移動一位,導致最右邊空出一位)
最右邊空出一位,補0
0000 0000 0000 0000 0000 0000 0000 1010 轉換成10進制數 為 10
?
右移 >>:
最右側位不要了, 最左側補符號位
這里我就舉6
0(最高位/符號位) 000 0000 0000 0000 0000 0000 0000 0110 (6)
6 >> 1 6的二進制位 右移1位
000 0000 0000 0000 0000 0000 0000 0011(最右側的零其實已經擠掉了,由于整個二進制數向右移動一位,導致最左邊空出一位)
補位, 按照原先的6的二進制數的最高位(符號位進行補位),1為負,0為正
是 0(正)就補0,是1(負)就補1
因為 6 的原先的二進制數的最高位是 0(正),所以我們要補個零
0000 0000 0000 0000 0000 0000 0000 0011 轉換成10進制數 為 3
?
在假設一個 負數 -1
1111 1111 這里我們只寫8位
-1 >> 1
111 1111 (最右側的一其實已經擠掉了,由于整個二進制數向右移動一位,導致最左邊空出一位)
補位, 按照原先的 -1 的二進制數的最高位(符號位進行補位),1為負,0為正
是 0(正)就補0,是1(負)就補1
因為 -1 的原先的二進制數的最高位是 1(負),所以我們要補個1
1111 1111 你會發現結果跟原來的二進制碼相比,沒有任何變化
?
無符號右移 >>>
最右側位不要了, 最左側補 0
這回特別點,0x ff ff ff ff
11111111 11111111 11111111 11111111
ff ff ff ff
0xffffffff >>> 1 :意思是0xffffffff 無符號右移一位
1111111 11111111 11111111 11111111
最左側補 0(無符號右移,不管你符號位是0還是1,統一補0)
0111 1111 11111111 11111111 11111111
0x 7 f f f f f f f
另外請記住 在Java中是沒有 無符號左移的,沒有意義
左移都是補零,(因為二進制數最右邊是沒有符號位的,所以統一補0)
?
注意:
1. 左移 1 位, 相當于原數字 * 2. 左移 N 位, 相當于原數字 * 2 的N次方.
2. 右移 1 位, 相當于原數字 / 2. 右移 N 位, 相當于原數字 / 2 的N次方.
3. 由于計算機計算移位效率高于計算乘除, 當某個代碼正好乘除 2 的N次方的時候可以用移位運算代替.
4. 移動負數位或者移位位數過大都沒有意義(二進數數只有32位,你要移動35位,沒意義)
?
條件運算子
條件運算子只有一個:
運算式1 ? 運算式2 : 運算式3
又稱 三目運算子
意思是 運算式1 為真,回傳運算式2,為假,回傳運算式3
意味著 運算式1必須為 布爾運算式
舉個例子 求兩個數的最大值
public class JavaFirst{
public static void main(String[] args) {
int a = 10;
int b = 20;
int max = a > b ? a : b;
// 該三目運算子表達的意思是
//如果 a大于b為真(true) ,回傳 a
//否則(a其實是小于b的) 為 假(false),回傳b
// 這里 b 是大于 a的,不滿足 a 大于 b的條件
// 所以為假(false),回傳 b(20)
System.out.println(max);
}// 圖53
}
圖53

?
運算子的優先級
程式一
public class JavaFirst{
public static void main(String[] args) {
System.out.println(1 + 2 * 3);
}//結果為 7, 說明先計算了 2*3 , 再計算 1+
// 圖54
}
圖 54

?
接著程式一, 如果你想算出 9,用小括號將 1 和 2 括起來
因為小括號的優先最高,將其括起來,編譯器先計算 小括號里的內容
程式如下
public class JavaFirst{
public static void main(String[] args) {
System.out.println((1 + 2) * 3);
}//結果為 9, 說明先計算了小括號里 1+2 , 再計算 *3
// 圖55
}
圖 55

?
運算子之間是有優先級的. 具體的規則我們不必記憶. 只需要根據自己的邏輯加括號就可以
小結
1. % 操作再 Java 中也能針對 double 來計算.
2. 需要區分清楚 前置自增 和 后置自增之間的區別.
3. 由于 Java 是強型別語言, 因此對于型別檢查較嚴格, 因此像 && 之類的運算運算元必須是 boolean.
4. 要區分清楚 & 和 | 什么時候是表示按位運算, 什么時候表示邏輯運算.
整體來看, Java 的運算子的基本規則和 C 語言基本一致
本文在這里結束了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/321227.html
標籤:java
