Java 學習筆記
dos 環(huán)境下(Windows 即 cmd)的 Java 命令
- 先用
javac 文件名.java;
命令,編譯 java 文件,生成一個后綴為 class、名與類名相同的文件。 - 再用
java 類名
命令,執(zhí)行文件。
當類名前的修飾符為 public 時,類名必須和源文件名一致。并且以上操作不能執(zhí)行帶 package 的 java 文件。
注釋
和 C 語言一樣。
//
:單行注釋。
/**/
:多行注釋。
編譯后生成的 class 文件里沒有注釋里的內容,即寫再多的注釋,class 文件的大小也不會變。
/** *...*/
:文檔注釋,用javadoc -encoding UTF-8 -d mydir -version -author HelloWorld.java
命令后,會生成一個類似 API 文檔的網頁,注釋里的內容會成為網頁的一部分。
javadoc 和 java 文件間的內容都是命令行參數(shù)。
注意文檔注釋寫的位置,有些在類外,有些在類里面。
輸出
System.out.println()
:輸出數(shù)據(jù)之后,會換行。
當括號里不填內容時,相當于換行操作,等價于
System.out.print("\n")
。
System.out.print()
:輸出數(shù)據(jù)后,不換行。
pubilc 修飾符
同一源文件中可定義多個類,每個類都會生成一個 class 文件(字節(jié)碼文件),且 class 文件名與類名相同。
public 修飾的類在每個源文件中最多一個,且類名必須與源文件名相同。
包(package)
? 包(類似于文件夾,用于管理class文件)的命名采用域名倒置的規(guī)則;
標識符
命名規(guī)則
? 標識符可以包含字母,數(shù)字,_,$,但是不能以數(shù)字開頭,不能包含空格;
命名習慣
包名
多單詞組成時所有字母都小寫。
例如:java.lang、com.atguigu.bean 等。
類名、接口名
多單詞組成時,所有單詞的首字母大寫。
例如:HelloWorld、String、System 等。
變量名、方法名
多單詞組成時,第一個單詞首字母小寫,第二個單詞開始每個單
詞首字母大寫。
例如:age、name、bookName、main、binarySearch、getName 等。
在同一作用域下,不能聲明 2 個同名的變量。
常量名
所有字母都大寫。多單詞時每個單詞用下劃線連接。
例如:MAX_VALUE、PI、DEFAULT_CAPACITY 等。
基本數(shù)據(jù)類型
整型
Java 各整數(shù)類型有固定的表數(shù)范圍和字段長度,不受具體操作系統(tǒng)的影響,以保證 Java 程序的可移植性。
類型 | 占用存儲空間 | 表示范圍 |
---|---|---|
byte | 1 字節(jié) | -128 ~ 127 |
short | 2 字節(jié) | -215 ~ 215-1 |
int | 4 字節(jié) | -231 ~ 231-1(約21.4億) |
long | 8 字節(jié) | -263 ~ 263-1 |
定義 long 類型的變量,賦值時需要以"l"或"L"作為后綴。
開發(fā)過程中,整型變量通常聲明為 int 型。
整型常量默認為 int。
浮點型
浮點型有固定的表數(shù)范圍和字段長度,不受具體操作系統(tǒng)的影響。
類型 | 占用存儲空間 |
---|---|
float | 4 字節(jié) |
double | 8 字節(jié) |
定義 float 類型的變量,賦值時需要以"f"或"F"作為后綴。
float、double 的數(shù)據(jù)不適合在不容許舍入誤差的金融計算領域。如果需要精確數(shù)字計算或保留指定位數(shù)的精度,需要使用 BigDecimal 類。
字符型
char 占 2 個字節(jié)。值用單引號('')括起來,例子:char a = 'a';
、char b = '中';
char 和 int 、char 和 char 做運算會變?yōu)?int。
布爾型
boolean 類型數(shù)據(jù)只有兩個值:true、false,無其它
不可以使用 0 或非 0 的整數(shù)替代 false 和 true,這點和 C 語言不同,布爾型不能和其他基本數(shù)據(jù)類型做運算。
類型轉換
自動類型轉換
byte ,short,char ==> int ==> long ==> float ==> double
表示范圍小的可以轉變?yōu)楸硎痉秶蟮模皇强凑加么鎯臻g大小。float 能表示的數(shù)比 long 還大。
注:byte 和 byte 運算、byte 和 short 運算、short 和 short 運算,結果需要用 int 存儲。
byte a = 10; byte b = a + 12; //會報錯,算式里的整數(shù)常量 12 默認是 int ,需要用 int 變量接收 //浮點數(shù)同理,而浮點數(shù)常量默認為 double。
強制類型轉換
和 C 語言類似,但 String 類型不能通過強制類型()轉換為其他的類型,因為 String 不是基本數(shù)據(jù)類型。
引用數(shù)據(jù)類型
字符串
String 和基本數(shù)據(jù)類型(包括布爾型)可以用“+”拼接。
String a = "abc";
System.out.println(a+1); //結果是abc1,類型為字符串
進制
二進制
以0b
或0B
開頭。
int a = 0b110;//或者0B110
System.out.println(a); //輸出為:6,以10進制輸出
十進制
以0x
或0X
開頭,a-f不區(qū)分大小寫。
int a = 0x110;//或者0X110
System.out.println(a); //輸出為:272
計算機數(shù)據(jù)的存儲使用二進制補碼形式存儲,并且最高位是符號位。
- 正數(shù):最高位是 0。
- 負數(shù):最高位是 1。
正數(shù)的補碼與反碼、原碼一樣,稱為三碼合一。
負數(shù)的補碼與反碼、原碼不一樣:
-
負數(shù)的原碼:把十進制轉為二進制,然后最高位設置為 1。
-
負數(shù)的反碼:在原碼的基礎上,最高位不變,其余位取反(0 變 1,1 變0)。
-
負數(shù)的補碼:反碼加 1
最快方法是:除符號位、最后個 1 及以后的位不變,其余位全取反。
補碼轉原碼:最高位不變,其余位取反再加 1,因此也可以使用最快方法。
運算
運算符的細微差異
java 中的 % 是取余,商向 0 靠近。
System.out.print(-5%2); //本身商為 -2.5,但是向0取整則為 -2,余數(shù)為 -1
System.out.print(-5/2); //本身商為 -2.5,但是向0取整則為 -2,
python中 % 為取模,商向負無窮靠近。
print(5//2) #地板除,得 2.
print(5/2) #得2.5
print(-5%2) #本身商為 -2.5,但是向負無窮取整得 -3,取模為 1,-5 = 2*(-3) + 1
a+=2;
與a= a+2;
的細微差別,a+=2; int b =1000; a+=b;
中 a 的類型不會改變,比如 a 的類型為 byte,則運算完也為 byte,只是把高位拋棄,只看地位對應哪個值, -=、*=、 /=、%= ++
具有相同的性質。
short s1 = 10;
s1 += 2; //因為在得到 int 類型的結果后,JVM 自動會進行強制類型轉換,將 int 類型強轉成 short
s1++;
比較運算符
- 比較運算符的結果都是 boolean 型,也就是要么是 true,要么是 false。
-
> < >= <=
:只適用于基本數(shù)據(jù)類型(除 boolean 類型之外)。 -
== !=
:適用于基本數(shù)據(jù)類型和引用數(shù)據(jù)類型。
邏輯運算符
&
和 &&
:表示“且”。
|
和 ||
:表示“或”。
a&b
和a&&b
的區(qū)別在于 a 為 false 時,&
仍會判斷b,從而執(zhí)行b中的表達式,比如age++
;而&&
會短路,不再判斷 b。|
和||
同理,推薦使用&&
和||
。
^
:表示”異或“。
!
:表示“非”。
位運算符
a<<n
:左移 n 位,低位補0。在一定范圍內,相當于乘 2n(正負數(shù)都是),這里也涉及到自動類型轉換(byte、short 移位后會變?yōu)閕nt)。
有可能會移成負數(shù),把數(shù)值的 1 移到符號位。是移位時,移的是補碼。當左移的位數(shù) n 超過該數(shù)據(jù)類型的總位數(shù)時,相當于左移(n % 總位數(shù))位。
a>>n
:右移 n 位,高位補與符號位相同的值。在一定范圍內,相當于除 2n,然后向下取整(正負數(shù)都是),這里也涉及到自動類型轉換(byte、short 移位后會變?yōu)閕nt)。
a>>>n
::右移 n 位,高位補 0。(正數(shù)、負數(shù)都適用),這里也涉及到自動類型轉換(byte、short 移位后會變?yōu)閕nt)。
負數(shù)會變成正數(shù)。
a&b、a|b、a^b、~a
:都是用二進制補碼運算,運算時也包括了符號位。
條件運算符
c = 條件表達式 ? A : B;
表達式為true
執(zhí)行 c = A
,表達式為false
執(zhí)行 c = B
。也可以syetem.out.println(條件表達式 ? "我是A" : "我是B");
switch-case
寫法和 C 語言一樣,case 子句中的值必須是常量,不能是變量名或不確定的表達式值或范圍。
break 和 continue
break 語句出現(xiàn)在多層嵌套的語句塊中時,可以通過標簽指明要終止的是哪一層語句塊,continue 類似。
label1: for(...){ //for1
label2:for(...){ //for2
label3:for(...){ //for3
break label2; //跳出緊跟 label2 的這個循環(huán),即for2,再執(zhí)行for1。
}
}
}
continue 結束此次循環(huán),然后再次進入所屬循環(huán)語句的下輪循環(huán)。 若上面 break 換成 continue,則是跳出 for2,再進入 for2。
標簽語句只能用在循環(huán)的頭部。
Scanner
步驟:
-
導包:
import java.util.Scanner;
。 -
創(chuàng)建 Scanner 對象:
Scanner scan = new Scanner(System.in);
。 -
next() / nextXxx()
,來獲取指定類型的變量,如nextInt()
獲取一個 Int 型整數(shù),nextDouble()
獲取一個 Double 型浮點數(shù)。-
我們把 Scanner 看為 2 個過程,掃描和鍵入,掃描是去輸入緩沖區(qū)取數(shù)據(jù);鍵入是從鍵盤輸入數(shù)據(jù),以“換行符”作為結束的標志,即按下“Enter”鍵后才會結束。
-
next()
和nextLine()
都是讀取字符串的方法。 -
next()
和nextLine()
的鍵入過程相同,掃描過程不同。-
nextLine()
會讀入空格,即將空格看為字符串的一部分,只把“換行符”作為掃描結束的標志,并且把光標移到“換行符”后。 -
next()
會忽略掉有效字符之前遇到的空格,把有效字符后的“空格”以及“換行符”作為掃描結束的標志,并且光標停在結束符之前。nextInt()、nextDouble()
等和next()
掃描過程相同,只有nextLine()
很特殊。
-
-
這就會出現(xiàn)一個問題,先使用
nextInt()
,光標停在結束符之前,nextLine()
可能會讀到空字符串或者帶空格的臟數(shù)據(jù)。解決辦法:使用nextInt()
后,先調用nextLine()
把臟數(shù)據(jù)讀走,將光標移到“換行符”后,再用nextLine()
讀取需要的數(shù)據(jù),也就是使用 2 次nextLine()
。
-
-
釋放資源:
scan.close();
。
Math.random()
Math.random()
會返回范圍在 [0,1) 的 double 浮點數(shù)。
獲取 [a,b] 范圍內的隨機整數(shù):(int)(Math.random() * (b - a + 1))+a
,取整使得范圍從 [a,b+1) 變成[a,b]。
包(package)
在 IDEA 中,一個 Project 可以有多個 module,一個module 下可以有多個 package,一個 package 下可以有多個 class。
實際上就是把不同功能的 class 放到不同的文件夾下,package 的命名采用域名倒置的規(guī)則,比如 www.lc.com
下的包可以寫成 com.lc.包名
數(shù)組
數(shù)組本身是引用數(shù)據(jù)類型,而數(shù)組中的元素可以是任何數(shù)據(jù)類型,包括基本數(shù)據(jù)類型和引用數(shù)據(jù)類型。
一維數(shù)組
聲明數(shù)組
類型[] 數(shù)組名;
,例如int[] arr;
。
Java 中聲明數(shù)組時,不能指定長度。
未初始化的數(shù)組不能直接使用。
初始化
-
靜態(tài)初始化
初始化的同時賦初值。
- 寫法 1:
int[] arr = new int[]{1,2,3,4,5};
- 寫法 2:
int[] arr = {1,2,3,4,5};
,這種不能寫成int[] arr; arr = {1,2,3,4,5};
,因為編譯器識別出不來。
- 寫法 1:
-
動態(tài)初始化
-
int[] arr = new int[5];
,[] 中指定數(shù)組長度,但不賦初值。指定長度后,無法修改長度。arr.length 可以得到數(shù)組 arr 的長度。
當使用動態(tài)初始化創(chuàng)建數(shù)組時,元素值是默認值。
-
一維數(shù)組內存存儲
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);
}
只有在 new 數(shù)組對象時,才會在堆中分配。聲明數(shù)組只會在棧中分配。
二維數(shù)組
聲明二維數(shù)組
可以理解為一維數(shù)組的元素也是一維數(shù)組。
元素的數(shù)據(jù)類型[][] 二維數(shù)組的名稱;
,例如int[][] grades;
。
初始化
-
靜態(tài)初始化
int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
int[][] arr = {{1,2,3},{4,5,6},{7,8,9,10}};
-
動態(tài)初始化
- 指定內層一維數(shù)組長度,
int[][] arr = new int[3][2];
- 不指定內層一維數(shù)組長度,
int[][] arr = new int[3][]; arr[i] = new int[長度];
,在使用時,才具體指定 arr[i] 的長度。
arr.length 得到的是
new int[3][2];
中的 3,即二維數(shù)組能存儲3個一維數(shù)組;arr[0].length 得到的是第一個一維數(shù)組的長度,即 2。不指定內層一維數(shù)組長度時,若沒進行
arr[i] = new int[長度];
操作,直接使用 arr[i].length 會報錯。System.out.println(arr[i]);
打印的是 arr[i] 地址,若沒進行arr[i] = new int[長度];
操作,則打印:null,且System.out.println(arr[i][j]);
會報錯。 - 指定內層一維數(shù)組長度,
二維數(shù)組內存
Arrays 工具類
java.util.Arrays 類即為操作數(shù)組的工具類,包含了用來操作數(shù)組(比如排序和搜索)的各種方法。