Java的關鍵字對java的編譯器有特殊的意義,他們用來表示一種數據類型,或者表示程序的結構等,關鍵字不能用作變量名、方法名、類名、包名。
備註:不必死記硬背,如果使用關鍵字作爲標識符,編譯器能提示錯誤。
goto 是java的保留關鍵字,意思是java並沒有使用goto,以後是否使用未定。
就是程序員在定義java程序時,自定義的一些名字,例如helloworld 程序裏關鍵字class 後跟的Demo,就是我們定義的類名。類名就屬於標識符的一種。
標識符除了應用在類名上,還可以用在變量、函數名、包名上。(要求同學們先記住,以後會詳細見到這些)。
- 標識符由26個英文字符大小寫(a~zA~Z)、數字(0~9)、下劃線(_)和美元符號($)組成。
- 不能以數字開頭,不能是關鍵字
- 嚴格區分大小寫
- 標識符的可以爲任意長度
ComputeArea,radius,area $itcast _itcast gz_itcast
注意:由於Java嚴格區分大小寫,ITCAST 和itcast是完全不同的標識符
- 包名
多個單詞組成時所有字母小寫(例:package com.itcast)
- 類名和接口
多個單詞組成時所有單詞的首字母大寫(例:HelloWorld)
- 變量名和函數名
多個單詞組成時第一個單詞首字母小寫,其他單詞首字母大寫(例:lastAccessTime、getTime)。
- 常量名
多個單詞組成時,字母全部大寫,多個單詞之間使用_分隔(例:INTEGER_CACHE)
注意:只是爲了增加規範性、可讀性而做的一種約定,標識符在定義的時候最 好見名知意,提高代碼閱讀性。
通過註釋提高程序的可讀性,是java程序的條理更加清晰,易於區分代碼行與註釋行。另外通常在程序開頭加入作者,時間,版本,要實現的功能等內容註釋,方便後來的維護以及程序員的交流。
1.單行註釋(line comment)用//表示,編譯器看到//會忽略該行//後的所文本
2.多行註釋(block comment)用/**/表示,編譯器看到/*時會搜索接下來的*/,忽略掉/**/之間的文本。
3.文檔註釋用/** */表示,是java特有的註釋,其中註釋內容可以被JDK提供的工具 javadoc 所解析,生成一套以網頁文件形式體現的該程序的說明文檔。
public static void main(String[] args) { // 第一步: 獲取半徑?並將半徑保存在程序中 double radius = 5; // 第二步:計算面積,並將面積保存在程序中 /* double area = radius * radius * 3.1415; // 第三步:在控制檯現實面積 System.out.println("半徑爲" + radius + "的圓的面積爲:" + area); */
} |
注意:多行註釋中可以嵌套單行註釋,多行註釋不能嵌套多行註釋。錯誤!!!
class Demo{ /* 這是主函數,是程序的入口 它的出現可以保證程序的獨立運行 /* 注意:多行註釋嵌套多行註釋是不行的。 */ */ public static void main(String[] args){ //這是輸出語句用於將括號內的數據打印到控制檯。 System.out.println("hello java"); } |
文檔註釋 (編寫軟件說明書)
- 需要使用sum給我們提供的javadoc工具生成一個html的說明文檔。
- 只能抽取public的屬性或者方法內容。
格式:
Javadoc –d 指定存儲文檔的路徑 -version –author(可選) 目標文件 |
@author 作者
@version 版本
@param 方法的參數
@return 返回值
註釋的使用細節:
三種註釋可以出現在程序的任何地方,但是不推薦找任意位置。
1. 編程習慣:
1. 給那條語句進行說明,註釋應該寫在該語句的旁邊。
2. 單行註釋一般寫在語句的後面多行註釋和文檔註釋一般寫在語句的上面
注意:文檔註釋只能出現在類、屬性、方法的上面。
- 註釋的嵌套
1.單行註釋可以在單行註釋裏面。
2.多行註釋不能嵌套在多行註釋裏面。
3 註釋的調試作用:
1. 可以作爲初學者的調試方式。
2. 可以幫組初學者確定代碼的錯誤之處。
常量是指在程序運行過程中其值不能改變的量。
Java中常量的分類:
整數常量 : 所有整數
小數常量 : 所有小數
布爾常量 : 只有true和false
字符常量 :使用’’引起來的單個字符
字符串常量 :使用“”引起來的字符序列,“” 、“a” 、” ”
null常量 : 只有一個值null
3.char 類型
char類型表示的是單個字符類型,任何數據使用單引號括起來的都是表示字符。字符只能有一個字符,比如:普通的老百姓穿上軍裝就是軍人。
注意:特殊字符的轉義序列:轉義字符
轉義字符的概述:
特殊字符使用”\”把其轉化成字符的本身輸出,那麼使用”\”的字符稱作爲轉移字符。
需求:使用輸出語句,打印出帶引號的信息例如輸出。
System.out.println("teacher said"java is fun"");編譯是無法正常通過的。語法有錯誤,編譯器讀到第二個引號就認爲是字符串的結束,剩餘的不知道怎麼處理。如何解決這個問題:java中使用轉義字符來表示特殊的字符。一個轉義字符以反斜槓(\)開始。
問題:想要打印帶引號的字符串怎麼辦,就可以使用反斜槓(\)後跟字符,這個反斜槓就是轉義字符。
轉義字符 |
名稱 |
Unicode |
\b |
Backspace (退格鍵) |
\u0008 |
\t |
Tab (Tab鍵盤) |
\u0009 |
\n |
Linefeed (換行) |
\u000A |
\r |
Carriage Return(回車) |
\u000D |
\\ |
Backslash (反斜槓) |
\u005C |
\' |
Single Quote (單引號) |
\u0027 |
\" |
Double Quote (雙引號) |
\u0022 |
\r 表示接受鍵盤輸入,相當於按下回車。
\n 表示換行。
\t 製表符,相當於Table鍵
\b 退格鍵,相當於Back Space
\’ 單引號
\’’ 雙引號
\\ 表示一個斜跨
上述問問題解決:System.out.println("teacher said\"java is fun\"");
注意:換行符就是另起一行,回車符就是回到一行的開頭,所以我們平時編寫文件的回車符應該確切來說叫做回車換行符
4. boolean 類型
boolean由數學家Geogore Boole 發明
boolean 類型用來存儲布爾值,在java中布爾值只有2個,true和false。
boolean flag=true; flag=false; |
Java中這8中基本數據類型都是小寫的。
進制:進制是一種記數方式 ,可以用有限的數字符號代表所有的數值。由特定的數值組成。
- 十進制: 都是以0-9這九個數字組成,不能以0開頭。
- 二進制: 由0和1兩個數字組成。
- 八進制: 由0-7數字組成,爲了區分與其他進制的數字區別,開頭都是以0開始。
- 十六進制:由0-9和A-F組成。爲了區分於其他數字的區別,開頭都是以ox開始。
幾乎每個民族最早都使用都十進制計數法,這是因爲人類計數時自然而然地首先使用的是十個手指。 但是這不等於說只有十進制計數法一種計數方法。例如,世界各國在計算年月日時不約而同地使用“十二進制”12個月爲一年又如:我國過去16兩纔算爲一斤,這就是“十六進計數法”,一個星期七天,這個就是”七進制計算法”。 計算機是由邏輯電路組成,邏輯電路通常只有兩個狀態,開關的接通與斷開,這兩種狀態正好可以用“1”和“0”表示。
如果要在計算機裏面保存十進制的7.
十進制轉二進制的轉換原理:除以2,反向取餘數,直到商爲0終止。
二進制轉十進制的轉換原理:就是用二進制的每一個乘以2的n次方,n從0開始,每次遞增1。然後得出來的每個數相加
存在問題:書寫特別長,不方便記憶。
二進位制在計算機內部使用是再自然不過的。但在人機交流上,二進位制有致命的弱點——數字的書寫特別冗長。例如,十進位制的100000寫成二進位制成爲11000011010100000。爲了解決這個問題,在計算機的理論和應用中還使用兩種輔助的進位制——八進位制和十六進位制。二進位制的三個數位正好記爲八進位制的一個數位,這樣,數字長度就只有二進位制的三分之一,與十進位制記的數長度相差不多。例如,十進位制的100000寫成八進位制就是303240。十六進位制的一個數位可以代表二進位制的四個數位,這樣,一個字節正好是十六進位制的兩個數位。十六進位制要求使用十六個不同的符號,除了0—9十個符號外,常用A、B、C、D、E、F六個符號分別代表(十進位制的)10、11、12、13、14、15。這樣,十進位制的100000寫成十六進位制就是186A0。
- 八進制的特點
由數字0-7組成。即使用三個開關表示一個八進制數。
10進制轉換8進制原理:就是用十進制的數字不斷除於8,取餘數。
八進制轉十進制原理: 用把進制的數不斷乘以8的n次方,n從0開始,每次遞增1。
除了這種方法之外,我們還有另一種方法,因爲三個開關表示一個八進制數。
十進制與十六進制之間的轉換
十六進制特點:由0~9 a(10) b(11) c(12) d(13) e(14) f(15)組成。
十進制轉十六進制原理:就是不斷除以16,取餘數。
代碼體現:
人使用的十進制 、 計算機底層處理的數據是二進制、八進制、十六進制,
那麼如果給計算機輸入不同的進制數據呢?
- 變量的概述
用於存儲可變數據的容器。
- 變量存在的意義
計算機主要用於處理生活中的數據,由於生活中存在大量的可變數據,那麼計算機就必須具備存儲可變數據的能力。
比如:
1.時間每一秒都在發生變化,根據不同的時間要有不同的處理方式。
2.氣象站會根據溫度發佈天氣預報信號。
- 變量的特點
正常情況下牛奶盒裝的都是牛奶,而且會根據牛奶的多少去決定要多大的容量的牛奶盒,A和B兩位同學同時把牛奶盒放進籃子裏面,但是需要區分兩個牛奶盒是誰的,都需要在牛奶盒上做一個標誌。
特點:
根據上述變量的特點,所以我們聲明一個變量的時候需要確定變量的大小,類型、名字三個特點:
錯誤: 1024byte temp = 1000000;
錯誤原因,java有自己的變量類型。
1. 整型
byte 代表一個字節的大小 8bit 2(8) -128~127 256
short 代表兩個字節的大小 16bit 2(16) -2(15)~2(15)-1
int 代表四個字節的大小 32bit 2(32) -2(31)~2(31)-1
long 代表八個字節的大小 64bit 2(64) -2(63)~2(63)-1
如果一個數值沒有采取特殊的處理,那麼該整數默認的類型是int。
可以使用數值後面添加L或小寫L改變默認的整數類型。
2. 浮點型
float 代表四個字節的大小 32bit
double 代表八個字節的大小 64bit
java程序中所有的小數默認的類型是double類型,所以需要使用特殊的符號改變默認的小數類型。
3. 字符型
char 代表兩個字節的大小 16bit 2(16)
原理:將字符映射爲碼錶中對應的十進制數據加以存儲。
4. 布爾型
boolean 佔一個字節。只有true與false兩個值。
格式: 數據類型 變量名字1 , 變量名字2 ,……變量名字n ,; |
案例:
int i 聲明瞭一個整形的變量。
double d 聲明瞭一個double數據類型的變量
float f 聲明瞭一個float數據類型的變量。
備註:變量名的首字母都一般都是以小寫字母開始。
初始化方式1: 數據類型 變量名字 = 數值。
初始化方式2: 數據類型 變量名字 , 變量名字 = 數值。
案例:
方式1: double d = 3.14;
方式2: double d ; d = 3.14 ;
Java中可以進行不同數據類型的加減乘除運算嗎?是可以的。在算術運算符中已經體驗過如果兩個整數(int)相除會去掉小數部分。如果需要保留小數部分,可以讓除數或者被除數變爲double類型的(5變爲5.0)。其實Java是自動的將int的那個數變爲了double類型了也就是Java自動的將整數變爲了浮點數。例如5/2.0 其實是5.0/2.0
- 自動類型轉換(也叫隱式類型轉換)
可以將一個數賦值給更大數值範圍的變量,例如可以經byte 變量賦值給short變量可以將short變量賦值給int變量可以將int變量賦值給long變量。
Java內部其實做了工作就是自動將數值進行了類型提升,就叫做自動類型轉換(也叫隱式類型轉換)
byte b = 1; //00000001 short s = b; //00000000 00000001 int i = s; long lon = i; double d = lon; //1.0 |
自動類型轉換(也叫隱式類型轉換)
要實現自動類型的轉換,需要滿足兩個條件,第一兩種類型彼此兼容,第二目標類型取
值範圍必須大於源類型。所有的數字類型,包括整形和浮點型彼此都可以進行轉換。
例如:
byte b=100; int x=b; System.out.println(x);//程序把b結果自動轉換爲int類型。 |
- 強制類型轉換(也叫顯式類型轉換)
不可以將一個數值賦給範圍更小數值範圍的變量,除非進行類型轉換。
byte b = 100; b = b + 2; System.out.println(b); |
上述例子發生了什麼,發生了類型轉換。
b+2 遇到了加法運算,2默認是int類型,byte類型b變量存儲的值自動類型提升爲
了int類型。執行完加法運算後的結果就是int類型,想要將int的類型值放入到byte類型變量b中,無法放入,編譯報錯。
byte b=1; b=(byte)(b+2); |
當兩種類型彼此不兼容,或者目標類型取值範圍小於源類型(目標是byte源是int)
無法自動轉換,此時就需要進行強制類型轉換。
強制類型轉換需要注意:
損失精度!!!
int a=128; byte b=(byte)a; System.out.println(b);//-128 /* * 此時的強轉已經造成了數值的不準確 */ |
int
00000000 |
00000000 |
00000000 |
10000000 |
10000000 |
byte
再次分析此行代碼
byte b = 100; b = b + 2; System.out.println(b); |
編譯:提示如下錯誤。
3、類型轉換的原理
可以把byte 理解爲1兩的碗,short 2兩的碗,int 4兩的碗,long 8兩的碗。1兩碗的滿碗酒可以倒入 2兩 4兩 8兩的碗中。但是 4兩碗的酒倒入1兩碗的酒就有一些問題。
- 什麼時候要用強制類型轉換
比如小數部分只想保留整數部分.
一定要清楚要轉換的數據在轉換後數據的範圍內否則會損失精度.
public static void main(String[] args) { byte b = 100; b = (byte) (b + 2); System.out.println(b); // 102 //捨棄小數部分 double d=5.5; int num=(int)d; } |
- 表達式的數據類型自動提升
算術表達式,邏輯表達式
所有的byte型、short型和char的值將被提升到int型。
如果一個操作數是long型,計算結果就是long型;
如果一個操作數是float型,計算結果就是float型;
如果一個操作數是double型,計算結果就是double型。
分析 System.out.println(‘a’+1)結果?
自動類型提升
byte b = 3; int x = 4; x = x + b;// b會自動提升爲int 類型參與運算。 System.out.println(x);// 7
|
強制類型轉換
byte b = 2; /* * 強制類型轉換,強制將b+2強制轉換爲byte類型,再賦值給b */ b = (byte) (b + 2); System.out.println(b);// 4 |
思考1
byte b=126;
問:既然數據默認的有數據類型,那麼126 默認是int類型的,爲什麼存儲到byte類型時不會報錯呢。
126 是常量java在編譯時期會檢查該常量(每個常量)是否超出byte類型的範圍。如果沒有可以賦值。
思考2:byte b=128;能否正常的編譯和運行。
該語句會出現編譯錯誤,128超出了byte變量的存儲範圍,所以出現編譯錯誤。
思考2
byte b1=3,b2=4,b;
b=b1+b2;
b=3+4;
哪一句編譯失敗?爲什麼?
b =3+4, 3和4都是常量,所以java在編譯時期會檢查該常量(每個常量)是否超出byte類型的範圍。如果沒有可以賦值。例如b=128+1 就無法編譯通過。b=127+1;也是無法通過。
b =b1+b2 不可以,因爲b1 和b2 是變量,表達式求值時,變量值會自動提升爲int型,表達式結果也就成了int型,這是要賦值給byte型的b,必須進行強制類型轉換了。
6、System.out.println(‘a’+1)結果
美國人爲了讓計算機識別他們生活中的文字,讓二進制表示生活中的文字.所以一個字母代表了一個二進制.,二進制也有十進制的表現形式.,把生活中的字母都用數字來標識,例如97 代表a ,98 代表 b。打印’a’就把a作爲輸出顯示,沒有疑問。但是 ‘a’+1 有加號涉及到了運算。根據java自動類型提升規則,同樣道理 char 提升爲int 。就把’a’代表的數字體現了出來。a 表示的是97 97+1就是98; 那麼 想要查看98 表示的char 是什麼 怎麼實現呢 ?就要用到剛纔介紹的強制類型轉換了 System.out.println(char(‘a’+1));就取到了98 在ASCII碼錶中表示的字符。大寫A 和小寫a 在 ASCII有不同的表現。還有一個概念字符’1’ 在ASCII中 不是數字 1,可以運行代碼查看,到此就可以明白了char 類型,char類型也是可以參與運算的,爲什麼可以參與運算呢。因爲字符在ASCII表中都有對應的數字體現。所有的計算機兼容ASCII。
System.out.println('a'+1); //98
System.out.println((char)('a'+1)); //b
補充問題:
int i='a'+'b'; System.out.println(i);//結果? System.out.println("hello"+'j'); //結果? |
總結:
所有數值運算符都可以用在char型數據上,如果另一個操作數是一個數字或者字符,那麼char會自動提升爲int型,如果另一個操作數是字符串,那麼字符就會和字符串相連。
正負號(+,-)
除法
%取模
求餘數
取模的正負取決與被除數:
1. 自增
(++)前自增:先自增完畢,再運算整個表達式,語句分號前面的都是運算表達式;
後自增,先運算完整個表達式(分號前面的都是表達式),再進行自增;
備註:參與自增運算的操作數據每次會加1.
結論:
如果運算符在變量的前面,則該變量自增1或者自減1,然後返回的是變量的新值,如
果運算符在變量的後面,則變量也會自增或者自減1,但是返回的是變量原來的值。++在前就是先運算,再取值,++在後就是先取值,再運算。
自增自減運算符案例:
完成如下運算: 一; int i = 10; int newNum = 10 * i++; System.out.println(newNum);//? 二: int i = 10; int newNum = 10 * ++i;//? System.out.println(newNum); //? 一可以理解爲 int i = 10; int newNum = 10 * i; i = i + 1; 二可以理解爲 int i = 10; i = i + 1; int newNum = 10 * i;
|
練習:
- 使用程序判斷一個整數是偶數還是奇數
- 使用程序判斷假設今天是星期4,那麼問10天后的今天是星期幾?
- 將數值表達式使用java程序翻譯,並通過程序求出運算結果
其中int x=1;int y=2,int a=3,int b=4,int c=5;
案例一:
public static void main(String[] args) { // 判斷一個整數一奇數還是偶數 int x = -100; // 奇數是,1,3,5...偶數是2,4,6...顯然整數除2能整除,也就%(取模)結果爲0就是偶數。 int result = x % 2; System.out.println(result); // 使用判斷語句進行判斷。 if (result == 0) { System.out.println(x + "是偶數"); } else { System.out.println(x + "是奇數"); } } |
方案二 使用判斷該數結果是否是奇數。
(但是該算法有問題,如果被判斷的整數爲負數是否有效?)
public static void main(String[] args) { // 判斷一個整數一奇數還是偶數 int x = 1; // 奇數是,1,3,5...偶數是2,4,6...顯然奇數%的結果爲1. int result = x % 2; System.out.println(result); // 使用判斷語句進行判斷。 if (result == 1) { System.out.println(x + "是奇數"); } else { System.out.println(x + "是偶數"); } } |
改進
public static void main(String[] args) { // 判斷一個整數一奇數還是偶數 int x = -1; // 奇數是,1,3,5...偶數是2,4,6...顯然奇數%的結果爲1. int result = x % 2; System.out.println(result); // 使用判斷語句進行判斷。 if (result != 0) { System.out.println(x + "是奇數"); } else { System.out.println(x + "是偶數"); } } |
案例三:判斷星期
public static void main(String[] args) { // 設定今天是星期1,用int 1表示星期一,0表示星期天 int today = 1; // 十天後是星期幾?,一個星期是7天,7天之後又是星期1,可以用? int future = (today+10) % 7; if (future == 0) { System.out.println("10天后是星期天"); } else { System.out.println("10天后是星期:" + future); }
} |
案例4:
int x = 1; int y = 2; int a = 3; int b = 4; int c = 5; int result = (3 + 4 * x) / 5 - 10 * (y - 5) * (a + b + c) / x + 9* (4 / x + (9 + x) / y); System.out.println(result); // 442 |
= , +=, -=, *=, /=, %=
運算符 |
運算 |
範例 |
結果 |
= |
賦值 |
a=3,b=2 |
a=3,b=2 |
+= |
加等於 |
a=3,b=3;a+=b; |
a=5,b=2; |
-= |
減等於 |
a=3,b=2,a-=b; |
a=1,b=2; |
*= |
乘等於 |
a=3,b=2,a*=b; |
a=6,b=2 |
/= |
除等於 |
a=3,b=2,a/=b; |
a=1,b=2; |
%= |
模等於 |
a=3,b=2,a%=b; |
a=1,b=2 |
a+=b 可以想象成 a=a+b;
變量聲明完了之後,可以使用賦值語句(assignment statement)給變量賦一個值,Java中使用等號(=)作爲基本的賦值運算符(assignment operator),
格式如下:
variable = expression; 變量 = 表達式;
|
變量我們已經知道如何聲明,表達式具體如何定義?
表達式的定義:
表達式涉及到值(常量),變量和通過運算符計算出的值,以及他們組合在一起計算出的新值。
x =y+1;
例如:
public static void main(String[] args) { int x = 1; // 聲明int變量x, 賦值1給變量x int y = 0; // 聲明int變量y, 賦值0給變量y double area; // 聲明double變量area double radius = 1.0; // 聲明double變量radius,並賦值1.0給變量radius x = 5 * (3 / 2) + 3 * 2; // 將=右半部分表達式的計算結果賦值給變量x x = y + 1; // 將變量y和1的求和的值賦值給變量x area = radius * radius * 3.14159; // 將計算面積的值賦值給變量area } |
賦值運算符小問題
問題1: int x; Syst2intln(x = 1); 如何理解? 答:等價於 x=1; System.out.println(x); 注意:不能 1=x,變量名必須在賦值運算符的左邊。
|
問題二: int x; int y; int z; x = y = z = 100; 如何理解? 答:等價於 int x; int y; int z; z = 100; y = z; x = y;
|
問題三:short s1 = 1; s1= s1+1; s1+=1; 問:s1= s1+1; s1+=1; 與有什麼不同? 對於short s1 = 1; s1 = s1 + 1; 由於s1+1運算時會自動提升表達式的類型,所以結果是int型,再賦值給short類型s1時,編譯器將報告需要強制轉換類型的錯誤。 對於short s1 = 1; s1 += 1;由於 += 是java語言規定的運算符,java編譯器會對它進行特殊處理,因此可以正確編譯。
|
如何比較兩個值?使用比較運算符 3和5誰大,在java中如何比較?
比較運算符比較的兩邊操作數,結果都是boolean的,只有true和false兩種結果。
運算符 |
運算 |
例子 |
結果 |
== |
相等於 |
4= =3 |
false |
!= |
不等於 |
4!= 3 |
true |
< |
小於 |
4 < 3 |
flase |
> |
大於 |
4>3 |
true |
<= |
小於等於 |
4<=3 |
false |
>= |
大於等於 |
4>=3 |
true |
Instanceof |
檢查是否是類的對象 |
"hello"instanceof String |
true |
注意的細節:
1.使用比較運算符的時候,要求兩種數據類型必須一致。
byte、short、char 會自動提升至int。
什麼是邏輯運算符?連接比較運算符的符號稱之爲邏輯運算符。那麼爲什麼要連接比較運算符? 舉例:當你去公司應聘,招聘要求,男性(判斷爲真),並且開發經驗1年(判斷爲假)那麼,我們還適合去面試嗎,不能,因爲只滿足了一項,總體是不滿足的(總體結果爲假)。
邏輯運算符用於對boolean型結果的表達式進行運算,運算的結果都是boolean型。我們的比較運算符只能進行一次判斷,對於對此判斷無能爲力,那麼邏輯運算符就可以經將較運算符連接起來。
邏輯運算符用於連接布爾型表達式,在Java中不可以寫成3<x<6,應該寫成x>3 & x<6 。
“&”和“&&”的區別:單與時,左邊無論真假,右邊都進行運算;雙與時,如果左邊爲真,右邊參與運算,如果左邊爲假,那麼右邊不參與運算。
“|”和“||”的區別同理,雙或時,左邊爲真右邊不參與運算。
“ ^ ”異或與“|”或的不同之處是:當左右都爲true時,結果爲false。
& 與 | 或 ^ 異或 ! 非
1、& 與
true & true = true ; false & true= false; true & false = false; false & false= false;
|
總結 & 符號特點
& : 只要兩邊的boolean 表達式結果,有一個false.那麼結果就是false
只有兩邊都爲true ,將結果爲true.
2、| 或
true | true =true; ture | false =true; false | true =true; false | false =flase; |
總結 | : 兩邊只要有一個爲真結果就爲真,當兩邊同爲假時結果才爲假.
3、^ 異或
true ^ true =false; ture ^ false =true; false ^ true= true; false ^ false=flase; |
^ : 兩邊相同結果是false
兩邊不同結果是true;
4、! 非
!true = false !false= true
|
5、&& 短路
研究發現,&運算只有兩邊全爲真的時候,結果才爲真,那麼當左邊爲假的時候就沒有必要在進行判斷,&&就產生了。
int a =4;
a >3 && a< 6;
a >3 & a< 6 ;
在這種情況下世沒有區別的
如果:
a =2
a >3 & a< 6 2大於 3 爲假, 接着運算 2 小於6 爲真,總的結果爲假
a >3 && a< 6; 此時a 不大於3 結果爲false 右邊不運算了.即短路.所以&& 比& 效率稍微高了一點.
public static void main(String[] args) { int x = 0; int y = 1; if (x == 0 && y == 1) { System.out.println(x + y); } } |
按位操作符用來操作整數基本數據類型中的單個比特(bit),就是二進制,按位操作符會對兩個參數中對應的位(bit)執行布爾運算,最終生成一個結果。按位操作符來源於C語言面向底層的操作,Java設計的初衷是嵌入式電視機機頂盒,所以面向底層的操作也保留了下來。
任何信息在計算機中都是以二進制的形式保存的,”&”、“|”、“^”除了可以作爲邏輯運算符也可以作爲位運算符。位運算是直接對二進制進行運算。他們對兩個操作數中的每一個二進制位都進行運算。例如int是由32個二進制數組成,因此使用位運算符可以對整數值的二進制數進行運算。
位(bit)運算符:
位運算符
|
運算符含義
|
& |
與(AND) |
| |
或(OR) |
^ |
異或 |
~ |
取反 |
規則:
可以把1當做true 0當做false
只有參與運算的兩位都爲1,&運算的結果才爲1,否則就爲0。
只有參加運算的兩位都是0,| 運算的結果纔是0,否則都是1。
只有參加運算的兩位不同,^ 運算的結果才爲1,否則就爲0。
1、& 與運算
& 參見運算的兩位數都爲1,&運算符結果才爲1,否則就爲0。
6&3
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000010 |
& =2 |
2、| 或運算
| 參與運算的兩位都爲0,|運算的結果才爲0,否則就爲1。
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000111 |
| =7 |
|
|
|
|
|
3、^ 異或運算
^只有參加運算的兩位不同,^運算的結果才爲1,否則就爲0。
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000101 |
^ =5 |
- ~ 反碼
就是取反,二進制只有1和0,取反就是如果爲1,取反就是0,如果是0,取反就是1。
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1001 |
取反 -7 |
System.out.println(~6);//-7
結論:當參與取反的數值是正數時,把對應的值加上負號,再-1;
當參與取反的數值是負數時,把對應的值加上負號,再-1;
負數的表現形式就是對應的正數取反,再加1。負數的最高位肯定是1。
4、負數表示
負數對應的正數的二進制-1,然後取反。
-6
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1001 |
取反 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1010 |
加1 |
5、異或特點
一個數異或同一個數兩次,結果還是那個數. 用處一個簡單的加密思想.
6^3^3
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0011 |
^3 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0101 |
|
0000-0000 |
0000-0000 |
0000-0000 |
0000-0011 |
^3 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
結果是6 |
除了這些位運算操作,還可以對數據按二進制位進行移位操作,Java的移位運算符有三種。
練習:取出一個二進制的某一段。
使用異或(^)數據對數據加密
對兩個變量的值進行互換。
方式1:
對兩個變量進行值交換(不能使用第三個變量)
方式2:
兩個數相加的時候,值有可能超出int表示範圍,不推薦。
方式3:
該方式雖然效率高,而且避免了超出int值,但是可讀性較差。
三種方式都可以對兩個變量的值進行交換,但是推薦使用第一種。(面試除外)
<< 左移
>> 右移
>>> 無符號右移
位運算符 |
||
運算符 |
運算 |
範例 |
<< |
左移 |
3 << 2 = 12 --> 3*2*2=12 |
>> |
右移 |
3 >> 1 = 1 --> 3/2=1 |
>>> |
無符號右移 |
3 >>> 1 = 1 --> 3/2=1 |
& |
與運算 |
6 & 3 = 2 |
| |
或運算 |
6 | 3 = 7 |
^ |
異或運算 |
6 ^ 3 = 5 |
~ |
反碼 |
~6 = -7 |
位運算符的細節 |
|
<< |
空位補0,被移除的高位丟棄,空缺位補0。 |
>> |
被移位的二進制最高位是0,右移後,空缺位補0; 最高位是1,空缺位補1。 |
>>> |
被移位二進制最高位無論是0或者是1,空缺位都用0補。 |
& |
二進制位進行&運算,只有1&1時結果是1,否則是0; |
| |
二進制位進行 | 運算,只有0 | 0時結果是0,否則是1; |
^ |
任何相同二進制位進行 ^ 運算,結果是0;1^1=0 , 0^0=0
不相同二進制位 ^ 運算結果是1。1^0=1 , 0^1=1 |
技巧:可以理解爲二進制1就是true,0就是false。
案例:
1、左移 (算術移位)
3<< 2 是如何在計算機裏是實現的?
首先將3轉換爲2進制,
00000000 |
00000000 |
00000000 |
00000011 |
3 的二進制 |
||
00000000 |
00000000 |
00000000 |
000011 |
左移2位,砍掉高位 |
||
0000 0000 |
0000 0000 |
0000 0000 |
0000 1100 |
低位補0 |
結果是12,所以3<<2 =12;
結論:左移就相當於乘以2的位移個數次冪.
2、右移
6>>2
00000000 |
00000000 |
00000000 |
00000110 |
6的二進制 |
||
000000 |
00000000 |
00000000 |
00000001 |
右移10被砍掉 |
||
00000000 |
00000000 |
00000000 |
00000001 |
高位補0 |
結果是1,所以6>>2 =1;
結論一個數往左移越移越大,往右邊移越來越小.
推論
3<<2=12; 3<<1=6 ; 3<<3=24;
3*4=12 ; 3*2=6; 3*8=24;
3*22=12; 3*21=6 3*23 =24;
結論往左移幾位就是乘以2的幾次冪。
右移規律
6>>2=1 ;6>>1=3 ;
6/4=1 ; 6/2=3 ;
右移兩位就是除以 2的2次方,右移一位就是除以 2的一次方。
總結 :>> 是除以2的移動位數次冪
<< 是乘以2的移動位數次冪
用處:最快的運算是位運算。
練習:最有效率的方式算出2乘以8等於幾?
3、無符號右移 (邏輯移位)
通過演示發現右移時高位就空了出來, >> 右移時高位補什麼要按照原有 數據的最高位來決定。
1111-1111 1111-1111 1111-1111 1111-1010 -6>>2
1111-1111 1111-1111 1111-1111 1111-0010
最高位補什麼要看原有最高位是什麼
那麼使用>> 後原來是最高位1 的那麼空出來的最高位還是1 的,是0的還是0。
如果使用>>> 無論最高位是0還是1 空餘最高位都拿0 補,這就是無符號右移。
1111-1111 1111-1111 1111-1111 1111-1010 -6>>>2
001111-1111 1111-1111 1111-1111 1111-10
結果是;1073741822
格式
(條件表達式)?表達式1:表達式2;
如果條件爲true,運算後的結果是表達式1;
如果條件爲false,運算後的結果是表達式2;
示例:
1獲取兩個數中大數。
int x=3,y=4,z;
z = (x>y)?x:y;//z變量存儲的就是兩個數的大數。
int x = 1; int y = 2; int z; z = x > y ? x : y; System.out.println(z); //2 |
2判斷一個數是奇數還是偶數。
int x=5; System.out.println((x%2==0?"偶數":"奇數")); |
- 運算符的優先級與結合性