## Java的基本語法
每一種編程語言都有一套自己的語法規范,Java語言也不例外,同樣需要遵從一定的語法規范,如代碼的書寫、標識符的定義、關鍵字的應用等。因此要學好Java語言,首先需要熟悉它的基本語法。
#### Java代碼的基本格式
Java中的程序代碼都必須放在一個類中,初學者可以簡單地把類理解為一個Java程序。類需要使用class關鍵字定義,在class前面可以有一些修飾符,格式如下:
```
修飾符 class 類名 {
程序代碼
}
```
在編寫Java代碼時,需要特別注意幾個關鍵:
- Java中的程序代碼可分為結構定義語句和功能執行語句,其中,結構定義語句用于聲明一個類或方法,功能執行語句用于實現具體的功能。每條功能執行語句的最后都必須用分號(;)結束。如下面的語句:
```java
System.out.println("這是第一個Java 程序!");
```
值得注意的是,在程序中不要將英文的分號(;)誤寫成中文的分號(;),如果寫成中文的分號,編譯器會報告“illegalcharacter”(非法字符)這樣的錯誤信息。
- Java語言是嚴格區分大小寫的。在定義類時,不能將class寫成Class,否則編譯會報錯。程序中定義一個computer的同時,還可以定義一個Computer,computer和Computer是兩個完全不同的符號,在使用時務必注意。
- 在編寫Java代碼時,為了便于閱讀,通常會使用一種良好的格式進行排版,但這并不是必需的,我們也可以在兩個單詞或符號之間任意的換行,例如下面這段代碼的編排方式也是可以的。
```java
public class HelloWorld {public static void
main(String [
] args){System.out.println("這是第一個Java 程序!");}}
```
雖然Java沒有嚴格要求用什么樣的格式來編排程序代碼,但是,出于可讀性的考慮,應該讓自己編寫的程序代碼整齊美觀、層次清晰,通常會使用下面這種形式:
```java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("這是第一個Java 程序!");
}
}
```
- Java程序中一句連續的字符串不能分開在兩行中書寫,例如,下面這條語句在編譯時將會出錯:
```java
System.out.println("這是第一個
Java 程序!");
```
如果為了便于閱讀,想將一個太長的字符串分在兩行中書寫,可以先將這個字符串分成兩個字符串,然后用加號(+)將這兩個字符串連起來,在加號(+)處斷行。上面的語句可以修改成如下形式:
```java
System.out.println("這是第一個"+
"Java 程序!");
```
#### Java中的注釋
在編寫程序時,為了使代碼易于閱讀,通常會在實現功能的同時為代碼加一些注釋。注釋是對程序的某個功能或者某行代碼的解釋說明,它只在Java源文件中有效,在編譯程序時編譯器會忽略這些注釋信息,不會將其編譯到class字節碼文件中去。
Java中的注釋有三種類型,具體如下。
- 單行注釋
單行注釋通常用于對程序中的某一行代碼進行解釋,用符號“//”表示,“//”后面為被注釋的內容,具體示例如下:
```java
int c = 10; //定義一個整型變量
```
- 多行注釋
多行注釋顧名思義就是在注釋中的內容可以為多行,它以符號“/*”開頭,以符號“*/”結尾,多行注釋具體示例如下:
```java
/*int c = 10;
int x = 5; */
```
- 文檔注釋
文檔注釋是以“/**”開頭,并在注釋內容末尾以“*/”結束。文檔注釋是對一段代碼概括的解釋說明,可以使用javadoc命令將文檔注釋提取出來生成幫助文檔,關于這點將在后面的章節做詳細講解。
#### Java中的標識符
在編程過程中,經常需要在程序中定義一些符號來標記一些名稱,如包名、類名、方法名、參數名、變量名等,這些符號被稱為標識符。標識符可以由任意順序的大小寫字母、數字、下劃線(_)和美元符號($)組成,但標識符不能以數字開頭,不能是Java中的關鍵字。
下面的這些標識符都是合法的。
```
username
username123
user_name
_userName
$ username
```
注意,下面的這些標識符都是不合法的!
```
123username
class
98.3
Hello World
```
在Java程序中定義的標識符必須要嚴格遵守上面列出的規范,否則程序在編譯時會報錯。除了上面列出的規范,為了增強代碼的可讀性,建議初學者在定義標識符時還應該遵循以下規則:
- 包名所有字母一律小寫,例如cn.itcast.test。
- 類名和接口名每個單詞的首字母都要大寫,例如ArrayList、Iterator。
- 常量名所有字母都大寫,單詞之間用下劃線連接,例如DAY_OF_MONTH。
- 變量名和方法名的第一個單詞首字母小寫,從第二個單詞開始每個單詞首字母大寫,例如lineNumber、getLineNumber。
- 在程序中,應該盡量使用有意義的英文單詞來定義標識符,使得程序便于閱讀。
- 例如使用userName表示用戶名,passWord表示密碼。
#### Java中的關鍵字
關鍵字是編程語言里事先定義好并賦予了特殊含義的單詞,也稱作保留字。和其他語言一樣,Java中保留了許多關鍵字,例如,class、public等,下面列舉的是Java中所有的關鍵字。
```
abstract boolean break byte case
catch char const class continue
default do double else extends
false final finally float for
goto if implements import instanceof
int interface long native new
null package private protected public
return short static strictfp super
switch this throw throws transient
true try void volatile while
synchronized
```
上面列舉的關鍵字中,每個關鍵字都有特殊的作用。例如package關鍵字用于包的聲明,import關鍵字用于引入包,class關鍵字用于類的聲明。在本書后面的章節將逐步對其他關鍵字進行講解,在此沒有必要對所有關鍵字進行記憶,只需要了解即可。
使用Java關鍵字時,有幾個值得注意的地方:
- 所有的關鍵字都是小寫的。
- 程序中的標識符不能以關鍵字命名。
#### Java中的常量
常量就是在程序中固定不變的值,是不能改變的數據。例如數字1、字符'a'、浮點數3.2等。在Java中,常量包括整型常量、浮點數常量、布爾常量、字符常量等。
- 整型常量
整型常量是整數類型的數據,有二進制、八進制、十進制和十六進制4種表示形式,具體表示形式如下。
**二進制:**由數字0和1組成的數字序列。在JDK7.0中允許使用字面值來表示二進制數,前面要以0b 或0B 開頭,目的是為了和十進制進行區分,如0b01101100、0B10110101。
**八進制:**以0開頭并且其后由0~7范圍內(包括0和7)的整數組成的數字序列,如0342。
**十進制:**由數字0~9范圍內(包括0和9)的整數組成的數字序列。如198。
**十六進制:**以0x或者0X開頭并且其后由0~9、A~F(包括0和9、A 和F)組成的數字序列,如0x25AF。
需要注意的是,在程序中為了標明不同的進制,數據都有特定的標識,八進制必須以0開頭,如0711、0123;十六進制必須以0x或0X開頭,如0xaf3、0Xff;整數以十進制表示時,第一位不能是0,0本身除外。例如十進制的127,用二進制表示為01111111,用八進制表示為0177,用十六進制表示為0x7F或者0X7F。
- 浮點數常量
浮點數常量就是在數學中用到的小數,分為float單精度浮點數和double雙精度浮點數兩種類型。其中,單精度浮點數后面以F或f結尾,而雙精度浮點數則以D 或d結尾。當然,在使用浮點數時也可以在結尾處不加任何的后綴,此時虛擬機會默認為double雙精度浮點數。浮點數常量還可以通過指數形式來表示。具體示例如下:
```
2e3f 3.6d 0f 3.84d 5.022e+23f
```
上述列出的浮點數常量中用到的e和f,初學者可能會感到困惑,在后面將會詳細介紹。
- 字符常量
字符常量用于表示一個字符,一個字符常量要用一對英文半角格式的單引號' '引起來,它可以是英文字母、數字、標點符號以及由轉義序列來表示的特殊字符。具體示例如下:
```
'a' '1' '&' '\r' '\u0000'
```
上面的示例中,\' u0000'表示一個空白字符,即在單引號之間沒有任何字符。之所以能這樣表示,是因為Java采用的是Unicode字符集,Unicode字符以\u開頭,空白字符在Unicode碼表中對應的值為\'u0000'。
- 字符串常量
字符串常量用于表示一串連續的字符,一個字符串常量要用一對英文半角格式的雙引號""引起來,具體示例如下:
```
"HelloWorld" "123" "Welcome \n XXX" ""
```
一個字符串可以包含一個字符或多個字符,也可以不包含任何字符,即長度為零。
- 布爾常量
布爾常量即布爾型的兩個值true和false,該常量用于區分一個事物的真與假。
- null常量
null常量只有一個值null,表示對象的引用為空。關于null常量后面將會詳細介紹。
## Java中的變量
#### 變量的定義
在程序運行期間,隨時可能產生一些臨時數據,應用程序會將這些數據保存在一些內存單元中,每個內存單元都用一個標識符來標識。這些內存單元被稱為變量,定義的標識符就是變量名,內存單元中存儲的數據就是變量的值。接下來,通過具體的代碼來學習變量的定義。
```
int x = 0,y;
y = x + 3;
```
上面的代碼中,第一行代碼的作用是定義了兩個變量x和y,也就相當于分配了兩塊內存單元,在定義變量的同時為變量x分配了一個初始值0,而變量y沒有分配初始值,變量x和y在內存中的狀態如圖2-2所示。
第二行代碼的作用是為變量賦值,在執行第二行代碼時,程序首先取出變量x的值,與3相加后,將結果賦值給變量y,此時變量x和y在內存中的狀態發生了變化,如圖2-3所示。

#### 變量的數據類型
Java是一門強類型的編程語言,它對變量的數據類型有嚴格的限定。在定義變量時必須聲明變量的類型,在為變量賦值時必須賦予和變量同一種類型的值,否則程序會報錯。
在Java中變量的數據類型分為兩種,即基本數據類型和引用數據類型。Java中所有的數據類型如圖2-4所示。

其中,8種基本數據類型是Java語言內嵌的,在任何操作系統中都具有相同大小和屬性,而引用數據類型是在Java程序中由編程人員自己定義的變量類型。本章此處重點介紹的是Java中的基本數據類型,引用數據類型會在以后的章節中做詳細的講解。
- 整數類型變量
整數類型變量用來存儲整數數值,即沒有小數部分的值。在Java中,為了給不同大小范圍內的整數合理地分配存儲空間,整數類型分為4種不同的類型:字節型(byte)、短整型(short)、整型(int)和長整型(long),4種類型所占存儲空間的大小以及取值范圍。

表列出了4種整數類型變量所占的空間大小和取值范圍。其中,占用空間指的是不同類型的變量分別占用的內存大小,如一個int類型的變量會占用4個字節大小的內存空間。取值范圍是變量存儲的值不能超出的范圍,如一個byte類型的變量存儲的值必須是-27~27-1之間的整數。
在為一個long類型的變量賦值時需要注意一點,所賦值的后面要加上一個字母L(或小寫l),說明賦值為long類型。如果賦的值未超出int型的取值范圍,則可以省略字母L(或小寫l)。具體示例如下:
```
long num = 2200000000L; //所賦的值超出了int 型的取值范圍,后面必須加上字母L
long num = 198L; //所賦的值未超出int 型的取值范圍,后面可以加上字母L
long num = 198; //所賦的值未超出int 型的取值范圍,后面可以省略字母L
```
- 浮點數類型變量
浮點數類型變量用來存儲小數數值。在Java中,浮點數類型分為兩種:單精度浮點數(float)和雙精度浮點數(double)。double型所表示的浮點數比float型更精確,兩種浮點數所占存儲空間的大小以及取值范圍。

表列出了兩種浮點數類型變量所占的空間大小和取值范圍,在取值范圍中,E表示以10為底的指數,E后面的+號和-號代表正指數和負指數,例如1.4E-45表示1.4*10-45。
在Java中,一個小數會被默認為double類型的值,因此在為一個float類型的變量賦值時需要注意一點,所賦值的后面一定要加上字母F(或者小寫f),而為double類型的變量賦值時,可以在所賦值的后面加上字符D(或小寫d),也可以不加。具體示例如下:
```
float f = 123.4f; //為一個float 類型的變量賦值,后面必須加上字母f
double d1 = 100.1; //為一個double 類型的變量賦值,后面可以省略字母d
double d2 = 199.3d; //為一個double 類型的變量賦值,后面可以加上字母d
```
在程序中也可以為一個浮點數類型變量賦予一個整數數值,例如下面的寫法也是可以的。
```
float f=100; //聲明一個float 類型的變量并賦整數值
double d=100; //聲明一個double 類型的變量并賦整數值
```
- 字符類型變量
字符類型變量用于存儲一個單一字符,在Java中用char表示。Java中每個char類型的字符變量都會占用2個字節。在給char類型的變量賦值時,需要用一對英文半角格式的單引號' '把字符括起來,如a' ',也可以將char類型的變量賦值為0~65535范圍內的整數,計算機會自動將這些整數轉化為所對應的字符,如數值97對應的字符為'a'。下面的兩行代碼可以實現同樣的效果。
```
char c = 'a'; //為一個char 類型的變量賦值字符'a'
char ch = 97; //為一個char 類型的變量賦值整數97,相當于賦值字符'a'
```
- 布爾類型變量
布爾類型變量用來存儲布爾值,在Java中用boolean表示,該類型的變量只有兩個值,即true和false。具體示例如下:
```
boolean flag = false; //聲明一個boolean 類型的變量,初始值為false
flag = true; //改變flag 變量的值為true
```
#### 變量的類型轉換
在程序中,當把一種數據類型的值賦給另一種數據類型的變量時,需要進行數據類型轉換。根據轉換方式的不同,數據類型轉換可分為兩種:自動類型轉換和強制類型轉換。
- 自動類型轉換
自動類型轉換也叫隱式類型轉換,指的是兩種數據類型在轉換的過程中不需要顯式地進行聲明。要實現自動類型轉換,必須同時滿足兩個條件,第一是兩種數據類型彼此兼容,第二是目標類型的取值范圍大于源類型的取值范圍。例如:
```
byte b = 3;
int x = b; //程序把byte 類型的變量b 轉換成了int 類型,無須特殊聲明
```
上面的語句中,將byte類型的變量b的值賦給int類型的變量x,由于int類型的取值范圍大于byte類型的取值范圍,編譯器在賦值過程中不會造成數據丟失,所以編譯器能夠自動完成這種轉換,在編譯時不報告任何錯誤。
除了上述示例中演示的情況,還有很多類型之間可以進行自動類型轉換,接下來就列出3種可以進行自動類型轉換的情況,具體如下:
1. 整數類型之間可以實現轉換,如byte類型的數據可以賦值給short、int、long類型的變量,short、char類型的數據可以賦值給int、long類型的變量,int類型的數據可以賦值給long類型的變量。
3. 整數類型轉換為float類型,如byte、char、short、int類型的數據可以賦值給float類型的變量。
5. 其他類型轉換為double類型,如byte、char、short、int、long、float類型的數據可以賦值給double類型的變量。
- 強制類型轉換
強制類型轉換也叫顯式類型轉換,指的是兩種數據類型之間的轉換需要進行顯式地聲明。當兩種類型彼此不兼容,或者目標類型取值范圍小于源類型時,自動類型轉換無法進行,這時就需要進行強制類型轉換。
```java
public class Example01 {
public static void main(String[] args) {
int num = 4;
byte b = num;
System.out.println(b);
}
}
```
編譯程序報錯

出現這樣錯誤的原因是將一個int型的值賦給byte類型的變量b時,int類型的取值范圍大于byte類型的取值范圍,這樣的賦值會導致數值溢出,也就是說一個字節的變量無法存儲四個字節的整數值。
在這種情況下,就需要進行強制類型轉換,具體格式如下:
```
目標類型 變量 = (目標類型)值
```
將例中第4行代碼修改為下面的代碼:
```
byte b = (byte) num;
```
再次編譯后,程序不會報錯,運行結果如圖所示。

需要注意的是,在對變量進行強制類型轉換時,會發生取值范圍較大的數據類型向取值范圍較小的數據類型的轉換,如將一個int類型的數轉為byte類型,這樣做極容易造成數據精度的丟失。
#### 變量的作用域
在前面介紹過變量需要先定義后使用,但這并不意味著在變量定義之后的語句中一定可以使用該變量。變量需要在它的作用范圍內才可以被使用,這個作用范圍稱為變量的作用域。在程序中,變量一定會被定義在某一對大括號中,該大括號所包含的代碼區域便是這個變量的作用域。接下來通過一個代碼片段來分析變量的作用域,具體如下:

上面的代碼中,有兩層大括號。其中,外層大括號所標識的代碼區域就是變量x的作用域,內層大括號所標識的代碼區域就是變量y的作用域。
## Java中的運算符
在程序中經常出現一些特殊符號,如+、-、*、=、>等,這些特殊符號稱作運算符。運算符用于對數據進行算術運算、賦值和比較等操作。在Java中,運算符可分為算術運算符、賦值運算符、比較運算符、邏輯運算符和位運算符。
#### 算術運算符
算術運算符用在數學表達式中,它們的作用和在數學中的作用一樣。下表列出了所有的算術運算符。
表格中的實例假設整數變量A的值為10,變量B的值為20:
| 操作符 | 描述 | 例子 |
| ------------ | ------------ | ------------ |
| + | 加法 - 相加運算符兩側的值 | A + B 等于 30 |
| — | 減法 - 左操作數減去右操作數 | A – B 等于 -10 |
| * | 乘法 - 相乘操作符兩側的值 | A * B等于200 |
| / | 除法 - 左操作數除以右操作數 | B / A等于2 |
| % | 取余 - 左操作數除以右操作數的余數 | B%A等于0 |
| ++ | 自增: 操作數的值增加1 | B++ 或 ++B 等于 21 |
| -- | 自減: 操作數的值減少1 | B- - 或 - -B 等于 19 |
**注意**
自增(++)自減(- -)運算符是一種特殊的算術運算符,在算術運算符中需要兩個操作數來進行運算,而自增自減運算符是一個操作數。
**前綴自增自減法(++a, - -a):** 先進行自增或者自減運算,再進行表達式運算
int a = 10;
int b = ++a;
最后結果為:a = 10,b = 11;
**后綴自增自減法(a++, a- -):** 先進行表達式運算,再進行自增或者自減運算
int a = 10;
int b = a++;
最后結果為:a = 10,b = 10;
#### 賦值運算符
下面是Java語言支持的賦值運算符:
| 操作符 | 描述 |例子 |
| ------------ | ------------ | ------------ |
|= | 簡單的賦值運算符,將右操作數的值賦給左側操作數 | C = A + B將把A + B得到的值賦給C |
|+ = | 加和賦值操作符,它把左操作數和右操作數相加賦值給左操作數 | C + = A等價于C = C + A |
|- = | 減和賦值操作符,它把左操作數和右操作數相減賦值給左操作數 | C - = A等價于C = C - A |
|* = | 乘和賦值操作符,它把左操作數和右操作數相乘賦值給左操作數 | C * = A等價于C = C * A |
|/ = | 除和賦值操作符,它把左操作數和右操作數相除賦值給左操作數 | C / = A等價于C = C / A |
|(%)= | 取模和賦值操作符,它把左操作數和右操作數取模后賦值給左操作數 | C%= A等價于C = C%A |
|<< = | 左移位賦值運算符 | C << = 2等價于C = C << 2 |
|>> = | 右移位賦值運算符 | C >> = 2等價于C = C >> 2 |
|&= | 按位與賦值運算符 | C&= 2等價于C = C&2 |
|^ = | 按位異或賦值操作符 | C ^ = 2等價于C = C ^ 2 |
| l= | 按位或賦值操作符 | C = 2等價于C = C I 2 |
#### 比較運算符
下表為Java支持的關系運算符
表格中的實例整數變量A的值為10,變量B的值為20:
| 操作符 | 描述 |例子 |
| ------------ | ------------ | ------------ |
|== | 檢查如果兩個操作數的值是否相等,如果相等則條件為真 | (A == B)為假(非真) |
|!= | 檢查如果兩個操作數的值是否相等,如果值不相等則條件為真 | (A != B) 為真 |
|> | 檢查左操作數的值是否大于右操作數的值,如果是那么條件為真 | (A> B)非真 |
|< | 檢查左操作數的值是否小于右操作數的值,如果是那么條件為真 | (A <B)為真 |
|>= | 檢查左操作數的值是否大于或等于右操作數的值,如果是那么條件為真 | (A> = B)為假 |
|<= | 檢查左操作數的值是否小于或等于右操作數的值,如果是那么條件為真 | (A <= B)為真 |
#### 邏輯運算符
下表列出了邏輯運算符的基本運算,假設布爾變量A為真,變量B為假
| 操作符 | 描述 |例子 |
| ------------ | ------------ | ------------ |
|&& | 稱為邏輯與運算符。當且僅當兩個操作數都為真,條件才為真。 | (A && B)為假 |
|II | 稱為邏輯或操作符。如果任何兩個操作數任何一個為真,條件為真。 | (A II B)為真 |
|! | 稱為邏輯非運算符。用來反轉操作數的邏輯狀態。如果條件為true,則邏輯非運算符將得到false。 | !(A && B)為真 |
#### 位運算符
Java定義了位運算符,應用于整數類型(int),長整型(long),短整型(short),字符型(char),和字節型(byte)等類型。
位運算符作用在所有的位上,并且按位運算。假設a = 60,b = 13;它們的二進制格式表示將如下:
A = 0011 1100
B = 0000 1101
A&b = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A= 1100 0011
下表列出了位運算符的基本運算,假設整數變量A的值為60和變量B的值為13:
| 操作符 | 描述 |例子 |
| ------------ | ------------ | ------------ |
|& | 如果相對應位都是1,則結果為1,否則為0 | (A&B),得到12,即0000 1100 |
|I | 如果相對應位都是0,則結果為0,否則為1 | (A I B)得到61,即 0011 1101 |
|^ | 如果相對應位值相同,則結果為0,否則為1 | (A ^ B)得到49,即 0011 0001 |
|? | 按位取反運算符翻轉操作數的每一位,即0變成1,1變成0。 | (?A)得到-61,即1100 0011 |
|<< | 按位左移運算符。左操作數按位左移右操作數指定的位數。 | A << 2得到240,即 1111 0000 |
|>> | 按位右移運算符。左操作數按位右移右操作數指定的位數。 | A >> 2得到15即 1111 |
|>>> | 按位右移補零操作符。左操作數的值按右操作數指定的位數右移,移動得到的空位以零填充。 | A>>>2得到15即0000 1111 |
#### 運算符的優先級

- 該表中優先級按照從高到低的順序書寫,也就是優先級為1的優先級最高,優先級14的優先級最低。
- 結合性是指運算符結合的順序,通常都是從左到右。從右向左的運算符最典型的就是負號,例如3+-4,則意義為3加-4,符號首先和運算符右側的內容結合。
- instanceof作用是判斷對象是否為某個類或接口類型,后續有詳細介紹。
- 注意區分正負號和加減號,以及按位與和邏輯與的區別
## 選擇結構語句
#### if條件語句
if(判斷條件) {滿足執行}
```java
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 20;
if (a == b) {
System.out.println("a 和 b 相等");
}
}
}
```
if(判斷條件) {滿足執行} else {不滿足執行}
```java
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 20;
if (a == b) {
System.out.println("a 和 b 相等");
} else {
System.out.println("a 和 b 不相等");
}
}
}
```
if中嵌套if
```java
public class Main {
public static void main(String[] args) {
int a = 10;
int b = 10;
int c = 20;
if (a == b) {
if (b == c) {
System.out.println("b 和 c 相等");
} else {
System.out.println("b 和 c 不相等");
}
} else {
System.out.println("a 和 b 不相等");
}
}
}
```
#### switch條件語句
```java
switch (表達式){
case 常量1:
// 代碼塊1;
break;
case 常量2:
// 代碼塊2;
break;
default:
// 代碼塊n;
break;
}
```
**關鍵字說明**
- switch:表示條件表達式,括號里的值是一個規定數據類型的值。
- case:表示條件分支,case后面跟一個常量,每個case后面的值必須不一樣。case的個數可以為0個。
- default:表示默認分支,default可以省略,通常放在最后。
- break:表示“停止”,跳出當前switch語句。
**switch支持的數據類型**
switch()括號中的表達式的結果的類型只能是特定類型,我們將一個double類型的變量放入,發現編譯報錯:Cannot switch on a value of type double. Only convertible int values, strings or enum variables are permitted。
不難看出這里括號中只支持是int,String,enum型的。
由于java中的類型的自動轉型,byte、char、short這三種可以自動轉換為int型的類型括號中也支持。
由于java中包裝類的自動拆箱,Integer、Byte、Char、Short這四種類型括號中也支持。
總結來說:switch()括號中的表達式支持int、String、enum以及可以自動轉型為int的其他類型。
**注意**
在Java1.6中表達式的類型只能為int和enum,在java1.7后支持了對String的判斷,String類型比較特殊。
```java
public class Main {
public static void main(String[] args) {
char grade = 'C';
switch(grade)
{
case 'A' :
System.out.println("優秀");
break;
case 'B' :
case 'C' :
System.out.println("良好");
break;
case 'D' :
System.out.println("及格");
case 'F' :
System.out.println("你需要再努力努力");
break;
default :
System.out.println("未知等級");
}
System.out.println("你的等級是 " + grade);
}
}
```
執行結果為:
```java
良好
你的等級是 C
```
說通俗一點就是當前的值,與下面的幾個值對比,如果相同的,就執行當前的case,如果找不到對應的值,就執行最后默認的default中的代碼。
## 循環結構語句
#### while循環語句
當滿足條件時,就循環執行while中的代碼塊,只要滿足,就會被循環執行。
```java
public class Main {
public static void main(String[] args) {
int x = 1;
while (x < 10) {
System.out.println("x 值為 : " + x);
x++;
}
}
}
```
執行結果為:
```java
x 值為 : 1
x 值為 : 2
x 值為 : 3
x 值為 : 4
x 值為 : 5
x 值為 : 6
x 值為 : 7
x 值為 : 8
x 值為 : 9
```
#### do…while循環語句
首先執行循環體,然后再判斷循環條件,如果循環條件不成立,則循環結束,如果循環條件成立,則繼續執行循環體。
```java
do{
循環體;
} while(循環條件);
```
```java
public class Main {
public static void main(String[] args) {
int i = 0;
do {
System.out.println("執行第 " + i + "次");
i++;
} while (i < 5);
}
}
```
執行結果為:
```java
執行第 0次
執行第 1次
執行第 2次
執行第 3次
執行第 4次
```
#### for循環語句
當變量滿足條件時,就一直循環下去,例子中,i的初始值為0,當滿足條件i < 5,就執行循環體中的代碼,i++表示沒執行一次就增加1
```java
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println("執行第 " + i + "次");
}
}
}
```
執行結果為:
```java
執行第 0次
執行第 1次
執行第 2次
執行第 3次
執行第 4次
```
#### 循環嵌套
嵌套的方式有很多種,這里舉例為for中嵌套for,在第一個的條件下,循環第二個for
```java
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < i + 1; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
```
執行結果為:
```java
*
**
***
****
*****
******
*******
********
*********
```
#### 跳轉語句
**break 退出循環**
下面的循環跳過了i為3的時候,結束循環。
```java
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
if (i == 3) {
break;
}
System.out.println("當前 i 為:" + i);
}
}
}
```
執行結果為:
```java
當前 i 為:0
當前 i 為:1
當前 i 為:2
```
**continue 跳過當前循環**
下面的循環跳過了i為3的時候,繼續循環后面的循環體。
```java
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue;
}
System.out.println("當前 i 為:" + i);
}
}
}
```
執行結果為:
```java
當前 i 為:0
當前 i 為:1
當前 i 為:2
當前 i 為:4
```
## 方法
#### 什么是方法
方法簡單的理解就是一段代碼塊,實現某種功能,也就是能被調用的獨立的代碼塊。下面是基本結構。
```Java
訪問修飾符 返回值類型 方法名(參數列表){
方法體
}
```
#### 訪問修飾符
**public**
用public修飾的類、類屬變量及方法,包內及包外的任何類(包括子類和普通類)均可以訪問。
**protected**
用protected修飾的類、類屬變量及方法,包內的任何類及包外那些繼承了該類的子類才能訪問。
**default**
如果一個類、類屬變量及方法沒有用任何修飾符,則其訪問權限為default(默認訪問權限)。默認訪問權限的類、類屬變量及方法,包內的任何類(包括繼承了此類的子類)都可以訪問它,而對于包外的任何類都不能訪問它(包括包外繼承了此類的子類)。default重點突出包。
**private**
用private修飾的類、類屬變量及方法,只有本類可以訪問,而包內包外的任何類均不能訪問它。
#### 訪問修飾符對比
| 級別 | 修飾符 | 同類 | 同包 | 子類 | 不同包 |
| ------------ | ------------ | ------------ | ------------ | ------------ |
| 公開 | public | √ | √ |√ | √ |
| 受保護| protected | √ | √ | √ | - |
| 默認 | 不寫修飾 | √ | √ | - | - |
| 私有 | private | √ | - | - | - |
#### 返回值類型
Java中的返回值類型,可以是任意一種類型,int,string,Object等,最為特殊的為void,這個類型表示當前方法不返回數據,還有一種為不寫返回值類型,這種方法稱為構造方法,后面會詳細講解。
#### 方法名
一般習慣命名為一下幾種:
- 包名:com.test.servlet
- 類名、接口名:UserService
- 變量名、方法名:userService
- 常量名:USER_SERVICE
#### 參數列表
一個方法可以不接受參數,接收多個參數,接收可變長度參數列表。
- 不接受參數:直接方法名()即可
- 多個參數:方法名(int a, String b, Object c)代表三個參數
- 可變長度參數列表:表示此處接受的參數為0到多個當前類型的對象,或者是一個當前類型的[],例如:方法名(Object ...ob)
#### 分析Main方法
```java
public class Main {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
```
public:訪問修飾符
static:表示靜態方法
void:無返回值
main:方法名
String[] args:參數
System:系統方法
out:標注輸入輸出
println:方法
#### 方法的重載
重載的特點:
- 方法名相同
- 方法的參數類型,參數個不一樣
- 方法的返回類型可以不相同
- 方法的修飾符可以不相同
下面是例子:
```java
public class Main {
public static void main(String[] args) {
Main main = new Main();
main.Test("湯姆");
main.Test(20);
}
public void Test(String userName) {
System.out.println("名字為:" + userName);
}
public void Test(int userAge) {
System.out.println("名字為:" + userAge);
}
}
```
#### 方法的遞歸
遞歸算法是一種直接或間接地調用自身的算法。
最典型的案例為算階乘,比如說數學計算階乘為:5!= 5 x 4 x 3 x 2 x 1,下面的例子就是Java實現階乘,這個思想重要。
```java
public class Main {
public static void main(String[] args) {
int num = factor(5);
System.out.println(num);
}
public static int factor(int n) {
if (n == 1) {
return 1;
} else {
int num = n * factor(n - 1);
return num;
}
}
}
```
運行結果為:
```java
120
```
## 數組
#### 數組的定義
Java 中定義數組的語法有兩種:
```java
type arrayName[]; // 例如:String myArray[];
type[] arrayName; // 例如:String[] myArray;
```
type 為Java中的任意數據類型,包括基本類型和組合類型,arrayName為數組名,必須是一個合法的標識符,[ ] 指明該變量是一個數組類型變量。
定義帶長度的數組,arraySize為長度,其格式如下:
```java
arrayName = new type[arraySize];
// 例如:myArray = new String[10];
```
通常可以定義時設置長度,語法為:
```java
type arrayName[] = new type[arraySize];
// 例如:String myArray[] = new String[10];
```
#### 數組的常見操作
```java
import java.util.*;
public class Main {
public static void main(String[] args) {
// 初始化數組
String[] array1 = {"馬超", "馬云", "關羽", "劉備", "張飛"};
String[] array2 = new String[]{"黃渤", "張藝興", "孫紅雷", "小豬", "牙哥", "黃磊"};
// 查看數組的長度
System.out.println("length: " + array1.length);
// 遍歷數組
for (int i = 0; i < array1.length; i++) {
System.out.println(array1[i]);
}
// 數組 int ---> string
int[] array3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
String arrStrings = Arrays.toString(array3);
System.out.println(arrStrings);
// 數組中是否包含某一個值
String a = "馬超";
if (Arrays.asList(array1).contains(a)) {
System.out.println("馬超在這里");
}
// 將數組轉成set集合
Set<String> set = new HashSet<>(Arrays.asList(array2));
System.out.println(set);
// 將數組轉成list集合
List<String> list = new ArrayList<>();
for (int i = 0; i < array2.length; i++) {
list.add(array2[i]);
}
String[] arrStrings2 = {"1", "2", "3"};
List<String> list2 = java.util.Arrays.asList(arrStrings2);
System.out.println(list2);
// 數組排序
int[] arr4 = {3, 7, 2, 1, 9};
Arrays.sort(arr4);
for (int i = 0; i < arr4.length; i++) {
System.out.println(arr4[i]);
}
// 從第幾個到第幾個之間的進行排序
int[] arr5 = {3, 7, 2, 1, 9, 3, 45, 7, 8, 8, 3, 2, 65, 34, 5};
Arrays.sort(arr5, 1, 4);
for (int i = 0; i < arr5.length; i++) {
System.out.println(arr5[i]);
}
// 復制數組
int[] arr6 = {3, 7, 2, 1};
int[] arr7 = Arrays.copyOf(arr6, 10); //指定新數組的長度
// 只復制從索引[1]到索引[3]之間的元素(不包括索引[3]的元素)
int[] arr8 = Arrays.copyOfRange(arr6, 1, 3);
for (int i = 0; i < arr8.length; i++) {
System.out.println(arr8[i]);
}
// 比較兩個數組
int[] arr9 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
boolean arr10 = Arrays.equals(arr6, arr9);
System.out.println(arr10);
// 去重復
// 利用set的特性
int[] arr11 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 3, 2, 4, 5, 6, 7, 4, 32, 2, 1, 1, 4, 6, 3};
Set<Integer> set2 = new HashSet<>();
for (int i = 0; i < arr11.length; i++) {
set2.add(arr11[i]);
}
System.out.println(set2);
int[] arr12 = new int[set2.size()];
int j = 0;
for (Integer i : set2) {
arr12[j++] = i;
}
System.out.println(Arrays.toString(arr12));
}
}
```
```java
public class Main {
public static void main(String[] args) {
int[] arr = {10, 2, 3, 4, 5, 6, 7, 8, 9, 0, 3, 2, 4, 5, 6, 7, 4, 32, 2, 1, 1, 4, 6, 3};
// 計算最大值
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
System.out.println("Max is " + max);
// 計算最小值
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
System.out.println("Min is " + min);
}
}
```
#### 冒泡排序法
```java
public class Main {
public static void main(String[] args) {
int[] array = new int[]{5, 3, 6, 2, 10, 2, 1};
for (int i = 0;i < array.length - 1; i ++) {
for (int j = i + 1;j < array.length;j ++) {
if (array[j] < array[i]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}
```
運行結果為:
```java
1 2 2 3 5 6 10
```
#### 選擇排序法
```java
public class Main {
public static void main(String[] args) {
int[] arr = new int[]{5, 3, 6, 2, 10, 2, 1};
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
// 如果后一個小于前一個,則把后一個放在最小
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// 交換當前索引 i 和最小值索引 minIndex 兩處的值
if (i != minIndex) {
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
// 執行完一次循環,當前索引 i 處的值為最小值,直到循環結束即可完成排序
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
```
運行結果為:
```java
1 2 2 3 5 6 10
```