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