本篇為Java基礎語法【上】,包含關鍵字、標識符、注釋、原碼反碼補碼、常量與變量、運算符這六部分內容。
關鍵字
定義:被Java語言賦予了特殊含義的單詞。
特點:關鍵字中所有字母都為小寫。

標識符
定義:在程序中自定義的一些名稱。由26個英文字母大小寫,數(shù)組:0-9,符號:_$組成。
定義合法標識符規(guī)則:
- 數(shù)字不可以開頭
- 不可以使用關鍵字
注意:
- Java中嚴格區(qū)分大小寫
- 在命名時,為了提高閱讀性,要盡量有意義
-
main不是關鍵字,因為函數(shù)名稱都是標識符,只是JVM識別main函數(shù),函數(shù)頭的格式必須固定
注釋
格式:
- 單行注釋
// - 多行注釋
/* */ - 文檔注釋
/** */
用途:
- 注解說明
- 調試程序
其中,單行注釋中可以嵌套單行/多行注釋,多行注釋中可以嵌套單行注釋,但不能嵌套多行注釋;對于單行和多行注釋,被注釋的文字,不會被編譯到字節(jié)碼(.class)文件中,因此不會被JVM解釋執(zhí)行;文檔注釋為Java特有的注釋,其中注釋內容可以被JDK提供的工具javadoc.exe所解析,生成一套以網(wǎng)頁文件形式體現(xiàn)的該程序的說明文檔。
文檔注釋的一般寫法:
/**
* 用于操作數(shù)組的工具類,其中包含獲取最值、排序等功能。
* @author LoisHuang
* @version 2019/7/9
*/
public class ArrayTool
{
/**
* 獲取整型數(shù)組的最大值
* @param arr 接收一個int類型的數(shù)組
* @return 該數(shù)組的最大的元素值
*/
public static int getMax(int[] arr)
{
...
}
}
注意可以通過javadoc命令生成說明文檔的類和方法必須是由public或protected修飾的,故私有的方法不用加文檔注釋,用多行注釋寫明功能即可。
tips:
- 面試:上機題,寫注釋
- 在看代碼的時候,可以通過寫注釋來檢驗是否看懂(代碼只是思想的一種表現(xiàn)形式)

原碼反碼補碼
(畢向東的Java基礎教程中沒有單獨講這一節(jié)的內容,但我認為對于后面的常量/變量以及運算符的理解非常有用。)
注意:原碼和反碼只是為了求負數(shù)的補碼,在計算機中沒有原碼、反碼的存在,只有補碼。
原碼
- 正數(shù)的原碼就是它本身
假設使用一個字節(jié)存儲整數(shù),整數(shù)10的原碼是:0000 1010 - 負數(shù)用最高位是1表示負數(shù)
假設使用一個字節(jié)存儲整數(shù),整數(shù)-10的原碼是:1000 1010
反碼
- 正數(shù)的反碼和原碼一樣
假設使用一個字節(jié)存儲整數(shù),整數(shù)10的反碼是:0000 1010 - 負數(shù)的反碼是負數(shù)的原碼按位取反(0變1,1變0),符號位不變
假設使用一個字節(jié)存儲整數(shù),整數(shù)-10的反碼是:1111 0101
補碼
再次強調,整數(shù)的補碼才是在計算機中的存儲形式。
- 正數(shù)的補碼和原碼一樣
假設使用一個字節(jié)存儲整數(shù),整數(shù)10的補碼是:0000 1010(第三次強調:這一串是10這個整數(shù)在計算機中存儲形式) - 負數(shù)的補碼是負數(shù)的反碼加1
假設使用一個字節(jié)存儲整數(shù),整數(shù)-10的補碼是:1111 0110(第三次強調:這一串是-10這個整數(shù)在計算機中存儲形式)
在計算機中,為什么不用原碼和反碼,而是用補碼呢?
因為在使用原碼、反碼計算時不準確,使用補碼計算時才準確。
使用原碼計算10-10
0000 1010 ?。?0的原碼)
+ 1000 1010 ?。?10的原碼)
------------------------------------------------------------
1001 0100 ?。ńY果為:-20,很顯然答案是否定的。)使用反碼計算10-10
0000 1010 (10的反碼)
+ 1111 0101 ?。?10的反碼)
------------------------------------------------------------
1111 1111 ?。ńY果為反碼,轉換成原碼為:1000 0000,最終的結果為:-0,很顯然答案是否定的。)使用補碼計算10-10
0000 1010 ?。?0的補碼)
+ 1111 0110 (-10的補碼)
------------------------------------------------------------
1 0000 0000 ?。ㄊ褂玫?個字節(jié)存儲,只能存儲8位,第9位的1沒地方存,就被丟棄了。故結果為:0。)
常量與變量
常量
概念:表示不能改變的值。
分類:
- 整數(shù)常量:所有整數(shù)
- 小數(shù)常量:所有小數(shù)
- 布爾(
boolean)型常量:較為特有,只有true/false兩個數(shù)值。 - 字符常量:將一個數(shù)字、字母或符號用單引號
' '標識 - 字符串常量:將一個或者多個字符用雙引號
" "標識 - null常量:只有一個
null數(shù)值
在Java中,整數(shù)有四種表現(xiàn)形式:二/八/十/十六進制。因為十進制非0開頭,所以其他進制的寫法,要前補0用于區(qū)分。二進制:0b 或 0B開頭;八進制:0開頭;十六進制:0x或0X開頭;負數(shù)前面加 -。
變量
概念:內存中的一個存儲區(qū)域,該區(qū)域有自己的名稱(變量名)和類型(數(shù)據(jù)類型),數(shù)據(jù)可以在同一類型范圍內不斷變化。
變量使用的兩個條件:有初始值和特定作用域。
數(shù)據(jù)類型:Java是強類型語言,對于每一種數(shù)據(jù)都定義了明確的具體數(shù)據(jù)類型,在內存中會分配不同大小的內存空間。

- 整數(shù)類型的存儲空間大小分別為1, 2, 4, 8byte,最常用的類型是
byte和int,默認類型為int; - 浮點型的存儲空間大小分別為4, 8byte,默認類型為
double; - 字符型(
char)的存儲空間大小為2byte。
注意:由于整數(shù)類型默認為int,因此若一個大于int類型范圍的整數(shù)常量賦值給long類型的變量時,結尾應該加上l,同理浮點型常量賦值給float類型的變量時,結尾加上f。
Example1
long a = 1234567891234l;
float b = 2.3f;
類型轉換&類型提升
針對于Java基礎數(shù)據(jù)類型。
- 自動類型轉換(隱式類型轉換)
兩種類型是彼此兼容的
-
轉換的目的類型占得空間范圍一定要大于轉化的源類型
正向過程:由低字節(jié)向高字節(jié)自動轉換,byte->short->int->long->float->double。
Example1-1short i = 5; int j = i;Example1-2
byte b = 4; //注意4為int類型(任何整數(shù)都為int)編譯器會判斷4是否在byte范圍內,如果在,則會做自動強轉。
-
強制類型轉換(顯示類型轉換)
格式:目標類型 變量 =(目標類型)源類型變量/常量
逆向過程:使用強制轉換,可能丟失精度,如int a=(int)3.14;。
Example2-1int i = 5; byte j = (int)i;Example2-2
byte b; b = 3; b = (byte)b*3 //編譯出錯,因為(byte)的運算級別比*高,所以會先轉換b后再*3 b = (byte)(b*3) //正確 -
數(shù)據(jù)類型自動提升(注意以下討論的是二元操作符)
Java定義了若干使用于表達式的類型提升規(guī)則:
a. 如果兩個操作數(shù)其中有一個是double類型,另一個操作就會轉換為double類型;
b. 否則,如果其中一個操作數(shù)是float類型,另一個將會轉換為float類型;
c. 否則,如果其中一個操作數(shù)是long類型,另一個會轉換為long類型;
d. 否則,兩個操作數(shù)都轉換為int類型。
(例外:final修飾的byte、short、char變量相加后不會被自動提升)
Example3-1System.out.println('a'); //輸出字母a System.out.println('a' + 1); //輸出98char型自動提升為int型。
Example3-2byte a = 1; byte b = 2; a = a + b; //自動類型提升成int,編譯出錯 a += b; //自加沒有自動類型提升問題把高字節(jié)轉成低字節(jié),需要作強制類型轉換:
a=(byte)(a+b);
Example3-3byte b1 = 1, b2 = 2, b3, b6; final byte b4 = 4,b5 = 6; b6 = b4 + b5; b3 = b1 + b2; //會發(fā)生編譯錯誤 System.out.println(b3 + b6);沒有
final修飾的變量相加后會被自動提升為int型,與目標類型byte不相容,需要強制轉換(向下轉型)。
Example3-4int x; int x1 = Integer.MAX_VALUE; int x2 = 2; x = x1 + x2; System.out.println(x); //輸出結果為-2147483647(其中Integer.MAX_VALUE為2147483647)默認
int類型,運算一旦超出范圍,會自動舍棄,保留原有位數(shù)。
注:Java內置Unicode國際標準碼表,ASCII為美國標準碼表,GBK為中國標準碼表,任何國家的碼表都兼容ASCII碼表。
運算符
注意:運算符都是有結果的。
算術運算符
-
+正號,-負號 -
+,-,*,/,%,加減乘除取模 -
++自增(前),++自增(后),--自減(前),--自減(后) -
+字符串相加,連接符
Example1:整數(shù)除法運算
int x = 6370;
x = x / 1000; //x的結果為?
對于除號/,它的整數(shù)除和小數(shù)除是有區(qū)別的:整數(shù)之間做除法時,只保留整數(shù)部分而舍棄小數(shù)部分。Java為強類型語言,因此x/1000,兩個int類型運算的值仍然為int類型。
Example2:負數(shù)取模運算
System.out.println(-5 % 2); //輸出-1
System.out.println(5 % -2); //輸出1
涉及到負數(shù)的模運算,只參考被模數(shù)(第一個數(shù))。
Example3-1:自增運算
int a = 3, b;
b = a++;
實際上運算過程為:由于a本身涉及到與b的運算,因此會先開辟一個臨時變量,存儲a當前的值(怕a的值改變),如temp=3;而賦值運算需要等右邊的運算先計算完成,于是現(xiàn)在計算右邊的a++,計算完a+1后賦值給a,于是a=4;最后再將temp賦值給b,如下圖所示:

Example3-2:自增運算
int i = 3;
i = i++;
System.out.println("i=" + i); //輸出i=3;
i = i++實際運算過程可理解為:
temp = i;
i = i + 1;
i = temp;
Example4-1:字符串相加
System.out.println(3 +"2");//輸出32
System.out.println("5+5=" + 5 + 5);//輸出5+5=55
+除字符串相加功能外,還能把非字符串轉換成字符串。
第一步"5+5=5"+5,第二步"5+5=55";若要輸出10,則可改為System.out.println("5+5="+(5+5));,輸出5+5=10。
任何數(shù)據(jù)只要和字符串進行+運算,都叫做相連接。用處如下:
Example4-2:同時輸出a與b的值
int a = 4, b = 5;
System.out.println("a=" + a +",b=" + b);
Example5:注意
int a = 3;
a + 1; //編譯錯誤:a+1不是語句
System.out.println("a=" + a);
賦值運算符
符號: =, +,=,-=, *=, /=, %=
Example1:+=簡單示例
int a, b, c;
a = b = c = 4;
a += 2; //將左右兩邊的和賦給左邊
Example2-1
short s = 3;
s = s + 4;//編譯錯誤,可能損失精度
System.out.println("s=" + s);
Example2-2
short s = 3;
s += 4;
System.out.println("s=" + s); //輸出s=7;
s = s + 4:編譯失敗,其為兩次運算,s會被提升為int型,運算后的結果還是int型,無法賦值給short型。
s += 4:編譯通過,其是賦值運算,為一次運算,與s = 3類似;+=運算符在給s賦值時,自動完成了強轉操作,其在內存中的形式為s = (short)(s + 4)。
比較運算符
符號:==,!=,<, >,<=,>=
instanceof 檢查是否是類的對象,"Hello" instanceof String 結果為true。
注意:比較運算符的結果都是boolean型。
邏輯運算符
定義:用來連接兩個boolean類型的表達式,結果為boolean型。

面試題 ——&與&&的區(qū)別:
&:左邊無論真假,右邊都進行運算。
&&:若左邊為真,右邊參與運算;若左邊為假,右邊則不參與運算。
|與||的區(qū)別同理,||:左邊為真,右邊不參與運算。
位運算符
注意在計算機系統(tǒng)中,數(shù)值一律用補碼來表示和存儲。

位運算是直接對二進制進行運算。特定情況下,計算方便,速度快,支持面廣;如果用算數(shù)方法,速度慢,邏輯復雜。位運算不限于一種語言,它是計算機的基本運算方法。
<<
相當于乘以2的倍數(shù)。
應用:最有效率的方式算出2乘以8的值,首選位運算(左移三位)。>>
符號位(最高位)是什么,就拿什么補空位。
正數(shù)的右移相當于除法,右移n位就除以2的n次方(n表示移動位數(shù)),如100>>4等效100/2^4
負數(shù)的右移不等于除法,即負數(shù)右移不能按除以2的n次方計算。>>>
數(shù)據(jù)右移時,高位出現(xiàn)的空位,無論原高位是什么,空位都用0補。&
應用:取一個數(shù)中的指定位。
例如:設X=1010 1110,取X的低四位,用X & 0000 1111=0000 1110即可得到。
方法:找一個數(shù),對應X要取的位,該數(shù)的對應位為1,其余位為零,此數(shù)與X進行“與運算”可以得到X中的指定位。-
^
應用:
1)與1相異或,使特定位翻轉
方法:找一個數(shù),對應X要翻轉的位,該數(shù)的對應為1,其余位為零,此數(shù)與X對應位異或即可。
例如:X=1010 1110,使X低四位翻轉,用X^0000 1111=1010 0001即可得到。
2)與0相異或,保留原值
例如:X^0000 0000 =1010 1110
3)交換兩個變量的值
int a = 3, b = 5;
a. 借助第三個變量來實現(xiàn)//開發(fā)時,使用第三方變量的形式,因為閱讀性強 int c; c = a; a = b; b = c;b. 利用加減法實現(xiàn)兩個變量的交換
//這種方式不要用,因為如果兩個整數(shù)的數(shù)值過大,會超出int范圍,數(shù)據(jù)會變化 a = a + b; // a = 3 + 5;a = 8; b = a - b; // 3+5-5 = 3;b = 3; a = a - b; // 3+5-3 = 5; a = 5;c. 用位異或運算來實現(xiàn),效率最高
原理:一個數(shù)異或同一個數(shù)兩次,結果還是這個數(shù)(即是一個數(shù)異或本身等于0且異或運算符合交換律)。//面試的時候用,閱讀性差 a = a ^ b; // a = 3 ^ 5; b = a ^ b; // b = (3 ^ 5) ^ 5; b = 3; a = a ^ b; // a = (3 ^ 5) ^ 3; a = 5; ~
對一個二進制數(shù)按位取反,即將0變?yōu)?,1變0。
注意計算機中數(shù)值一律用補碼來表示和存儲,因此負數(shù)取反過程:先用原碼表示,再轉化為補碼,補碼取反,最后轉化為原碼,才是負數(shù)取反的值。
三元運算符
格式:(條件表達式)?表達式1:表達式2
如果條件為true,運算后的結果是表達式1;如果條件為false,運算后的結果是表達式2;
Example1:獲取兩個整數(shù)中的較大的整數(shù)
int a = 3, b = 4;
int max = a > b ? a : b;
Example2:獲取三個整數(shù)中的較大的整數(shù)
int o = 3, p = 4, q = 5;
//易讀的寫法
int temp = o > p ? o : p;
int max = temp > q : temp : q;
//閱讀性較差的寫法
int max = (o > p ? o : p) > q : (o > p ? o : p) : q;
【參考文檔】:
1、Java基礎-原碼反碼補碼
2、java 基本數(shù)據(jù)類型及自動類型提升
3、java中的二進制以及基本位運算
4、右移運算符總結