日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747



JAVA中的操作符

Java是一門靜態(tài)強(qiáng)類型的語(yǔ)言,因此如果操作符接收的值的類型不符合操作符規(guī)定的類型,就會(huì)在編譯期產(chǎn)生編譯錯(cuò)誤,通常IDE會(huì)對(duì)這種情況進(jìn)行提示,所以Java的操作符不會(huì)跟JavaScript中的操作符那樣發(fā)生很多的類型轉(zhuǎn)換,其行為更具有確定性,所以只需要進(jìn)行簡(jiǎn)單的介紹。

運(yùn)算符說(shuō)明Java運(yùn)算符分隔符. [] (){} , ;單目運(yùn)算符++ -- - !強(qiáng)制類型轉(zhuǎn)換符(type)乘/除/求余* / %加/減+ -位移運(yùn)算符<< >> >>>關(guān)系運(yùn)算符< <= >= > instanceof等價(jià)運(yùn)算符== !=按位與&按位異或^按位或|條件與&& (短路)條件或|| (短路)三目運(yùn)算符?:賦值= += -=*= /= &=|= ^= %=<<= >>= >>>=

特別注意==和!=

==和!=這兩個(gè)操作符用來(lái)進(jìn)行相等性的判斷,但是需要注意的是,這類似于一個(gè)全等操作,對(duì)于基本類型的值來(lái)說(shuō)沒(méi)有任何問(wèn)題,但是對(duì)于引用類型的值來(lái)說(shuō),應(yīng)該采用對(duì)象內(nèi)部的equals()方法來(lái)進(jìn)行比較。

Java中的表達(dá)式和合法的語(yǔ)句

在程序設(shè)計(jì)語(yǔ)言中,表達(dá)式和語(yǔ)句是完全不同的兩個(gè)概念,在我的理解中:

  • 表達(dá)式是有值的,任何一個(gè)表達(dá)式計(jì)算完成之后都會(huì)返回一個(gè)結(jié)果值
  • 語(yǔ)句是一段可執(zhí)行的代碼,它不一定有值。
  • 表達(dá)式本身是可以作為語(yǔ)句存在的,我們稱之為表達(dá)式語(yǔ)句。

通過(guò)上面的介紹,我們可以認(rèn)為表達(dá)式是語(yǔ)句的一種特殊情況,表達(dá)式是具有值的語(yǔ)句

同時(shí),我們需要注意,在很多時(shí)候,我們提到語(yǔ)句的時(shí)候一般認(rèn)為語(yǔ)句是沒(méi)有值的,這種情況下的語(yǔ)句被狹義化了。

使用表達(dá)式的目的和合法的語(yǔ)句

程序中的許多動(dòng)作都是通過(guò)計(jì)算表達(dá)式而完成的,計(jì)算一個(gè)表達(dá)式要么是為了他們的副作用,例如對(duì)變量賦值;要么是為了得到他們的值,將其用做更大的表達(dá)式的引元或操作數(shù),要么用來(lái)改變語(yǔ)句的執(zhí)行順序(如if中接收bool值進(jìn)行流程控制),或者是同時(shí)為了這兩個(gè)目的

基于這個(gè)原因,很多的編程語(yǔ)言中如果一個(gè)表達(dá)式不滿足使用表達(dá)式的目的,那么這個(gè)表達(dá)式就不能作為一條單獨(dú)的語(yǔ)句存在,也就是說(shuō)不能運(yùn)行這個(gè)表達(dá)式,因?yàn)檫@其實(shí)是沒(méi)有任何意義的,在Java中就是這樣的,如下:

int a = 0;
int b = 1;
a+b; //ERROR,是一個(gè)正確的表達(dá)式,但是由于不能滿足使用表達(dá)式的目的,把他作為一個(gè)語(yǔ)句執(zhí)行沒(méi)有任何意義,所以Java認(rèn)為這不是一個(gè)合法的語(yǔ)句。
復(fù)制代碼

同時(shí)我們需要注意,賦值語(yǔ)句在Java中被認(rèn)為是表達(dá)式,所以賦值語(yǔ)句是有值的,如下:

public static void main(String[] args) {
 int a = 0;
 System.out.println(a = 3+2); //5
 System.out.println(a); //5
}
復(fù)制代碼

語(yǔ)句

我們接下來(lái)要討論的語(yǔ)句就是被狹義之后的語(yǔ)句,主要的功能是用于控制程序的執(zhí)行流程。

程序的三種基本結(jié)構(gòu)

無(wú)論我們使用哪種編程范式(無(wú)論是結(jié)構(gòu)化編程范式,面向?qū)ο蟮木幊谭妒竭€是函數(shù)式編程范式),書寫算法都是必須的,而算法的實(shí)現(xiàn)過(guò)程是由一系列操作組成的,這些操作之間的執(zhí)行次序就是程序的控制結(jié)構(gòu)。

在以前,很多編程語(yǔ)言都提供了goto語(yǔ)句,goto語(yǔ)句非常靈活,可以讓程序的控制流程任意流轉(zhuǎn)。但是goto語(yǔ)句太隨意了,大量使用goto語(yǔ)句會(huì)使得程序難以理解并且容易出錯(cuò)。

1996年,計(jì)算機(jī)科學(xué)家Bohm和Jacopini證明了這樣的事實(shí):**任何簡(jiǎn)單或者復(fù)雜的算法都可以有順序結(jié)構(gòu),分支(選擇)結(jié)構(gòu)和循環(huán)結(jié)構(gòu)這三種基本結(jié)構(gòu)組合而成。**所以這三種結(jié)構(gòu)就被稱為程序設(shè)計(jì)的三種基本結(jié)構(gòu)。

不論哪一種編程語(yǔ)言,都會(huì)提供兩種基本的流程控制結(jié)構(gòu):分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。

其中分支結(jié)構(gòu)用于實(shí)現(xiàn)根據(jù)條件來(lái)選擇性地執(zhí)行某段代碼,循環(huán)結(jié)構(gòu)則用于實(shí)現(xiàn)根據(jù)循環(huán)條件重復(fù)執(zhí)行某段代碼,通過(guò)這兩種控制結(jié)構(gòu),就可以改變程序原來(lái)順序執(zhí)行的順序,實(shí)現(xiàn)流程的控制進(jìn)而實(shí)現(xiàn)任意復(fù)雜的算法。

Java中也為我們提供了分支和循環(huán)語(yǔ)句,同時(shí)還提供了其他的一些語(yǔ)句用來(lái)更加靈活的控制程序流程。

順序結(jié)構(gòu)

任何編程語(yǔ)言中最常見(jiàn)的程序結(jié)構(gòu)就是順序結(jié)構(gòu)。順序結(jié)構(gòu)就是程序從上到下逐行地執(zhí)行,中間沒(méi)有任何判斷和跳轉(zhuǎn)。

如果一個(gè)方法的多行代碼之間沒(méi)有任何流程控制,則程序總是從上向下依次執(zhí)行,排在前面的代碼先執(zhí)行,排在后面的代碼后執(zhí)行。這意味著,沒(méi)有流程控制,Java中方法的語(yǔ)句是一個(gè)順序執(zhí)行流,從上向下依次執(zhí)行每一條語(yǔ)句

分支(選擇)結(jié)構(gòu)

Java中提供了兩種常見(jiàn)的分支控制結(jié)構(gòu):if語(yǔ)句和switch語(yǔ)句。其中if語(yǔ)句使用布爾表達(dá)式或者布爾值作為分支條件來(lái)進(jìn)行分支控制;而switch則用戶對(duì)多個(gè)值進(jìn)行匹配,從而實(shí)現(xiàn)分支控制。

if語(yǔ)句

if語(yǔ)句使用布爾表達(dá)式或者布爾值作為分支條件來(lái)進(jìn)行分支控制。if語(yǔ)句有如下三種形式:

if(logic expression) {
	statement...
}
復(fù)制代碼
if (logic expression) {
 statement...
} else {
 statement...
}
復(fù)制代碼
if (logic expression) {
 statement...
} else if(logic expression) {
 statement...
} ...
復(fù)制代碼

使用if語(yǔ)句的時(shí)候需要注意下面幾點(diǎn):

  • 當(dāng)if和else后面之后一條語(yǔ)句的時(shí)候可以省略{},但是通常最好不要省略{}
  • 對(duì)于if語(yǔ)句,還有一個(gè)很容易出現(xiàn)的邏輯錯(cuò)誤。看如下的程序:
int age = 45;
if (age > 20) {
 System.out.println("青年人");
} else if (age > 40) {
 System.out.println("中年人");
} else if (age > 60) {
 System.out.println("老年人");
}
復(fù)制代碼
  • 表面上看來(lái),上面的程序沒(méi)有任何問(wèn)題,但是age=45程序的運(yùn)行結(jié)果卻是“青年人”,這顯然是有問(wèn)題的!
  • **對(duì)于任何if else語(yǔ)句,表面上看起來(lái)else后沒(méi)有任何條件,或者esle if后面只有一個(gè)條件——但是這只是表面現(xiàn)象,因?yàn)閑lse的含義是"否則"——else本身就是一個(gè)條件!else的隱含條件是對(duì)前面的條件取反。**因此,上面的代碼可以修改為:
int age = 45;
if (age > 60) {
 System.out.println("老年人");
} else if (age > 40) {
 System.out.println("中年人");
} else if (age > 20) {
 System.out.println("青年人");
}
復(fù)制代碼
  • 上面的程序運(yùn)行之后就能得到正確的結(jié)果,其實(shí)上面的程序就等同于下面的這段代碼:
int age = 45;
if (age > 60) {
 System.out.println("老年人");
}
//在原本的if條件中增加了else的隱含條件
if (age > 40 && !(age > 60)) {
 System.out.println("中年人");
}
//在原本的if條件中增加了else的隱含條件
if (age > 20 && !(age > 40 && !(age > 60)) && !(age > 60) {
 System.out.println("青年人");
}
復(fù)制代碼
  • 也就是說(shuō)上面的判斷邏輯轉(zhuǎn)為如下三種情況:
  • age大于60歲,判斷為“老年人”
  • age大于40歲,并且age小于等于60歲,判斷為“中年人”
  • age大于20歲,并且age小于等于40歲,判斷為“青年人”。
  • 上面的邏輯才是實(shí)際希望的判斷邏輯。因此,使用if...else語(yǔ)句進(jìn)行流程控制的時(shí)候,一定不要忽略了else所帶的隱含條件。
  • 如果每次都去計(jì)算if條件和else條件的交集也是一件麻煩的事情,為了避免出現(xiàn)上述的錯(cuò)誤,在使用if...else語(yǔ)句的時(shí)候有一條基本規(guī)則: 總是優(yōu)先把包含范圍小(子集)的條件放在前面處理。
  • 如 age>60是age>40的子集,而age>40是age>20的子集,把自己放在前面進(jìn)行處理就可以避免忽略else的隱含條件而造成程序錯(cuò)誤。

switch語(yǔ)句

switch語(yǔ)句由一個(gè)控制表達(dá)式和多個(gè)case標(biāo)簽組成,switch語(yǔ)句根據(jù)表達(dá)式的值將控制流程轉(zhuǎn)移到了多個(gè)case標(biāo)簽中的某一個(gè)上。其形式如下:

switch (expression) {
 case value1: {
 statement...;
 break;
 }
 case value2: {
 statement...;
 break;
 }
 ...
 case valuen: {
 statement...;
 break;
 }
 default: {
 statement...;
 }
}
復(fù)制代碼

switch語(yǔ)句先執(zhí)行對(duì)expression的求職,然后依次匹配value1、value2...valuen,遇到匹配的值則從對(duì)應(yīng)的case塊開(kāi)始向下執(zhí)行代碼,如果沒(méi)有任何一個(gè)case塊能夠匹配,則會(huì)執(zhí)行default塊中的代碼。

switch支持的數(shù)據(jù)類型

Java7之后,對(duì)switch語(yǔ)句進(jìn)行了一定的增強(qiáng),switch語(yǔ)句后的控制表達(dá)式的數(shù)據(jù)類型只能是byte、short、char、int四種整型類型,還有枚舉類型和String類型。

  • switch中不支持浮點(diǎn)數(shù),因?yàn)槎M(jìn)制保存浮點(diǎn)數(shù)字不是完全精確的,所以對(duì)浮點(diǎn)數(shù)進(jìn)行相等性判斷并不可靠
  • switch中不支持boolean類型的數(shù)據(jù),因?yàn)閷?duì)于boolean類型,使用if語(yǔ)句是更好的選擇
  • switch中不支持long整型,我認(rèn)為一個(gè)原因是根本使用不了這么多的分支

同時(shí),我們需要注意的是,case關(guān)鍵字后面只能跟一個(gè)和switch中表達(dá)式的數(shù)據(jù)類型相同的常量表達(dá)式

switch的貫穿

需要注意的是,switch語(yǔ)句并不是一個(gè)多選一的分支控制語(yǔ)句,考慮到物理上的多種情況可能是邏輯上的一種情況,switch塊中語(yǔ)句的執(zhí)行會(huì)貫穿標(biāo)號(hào)”,除非遇到break語(yǔ)句。如下代碼:

public void switchTest(int a) {
 switch (a) {
 case 1: System.out.print("1");
 case 2: System.out.print("2");
 case 3: System.out.print("3");
 default: System.out.print("default");
 }
}
switchTest(1);
復(fù)制代碼

上面的代碼中執(zhí)行switchTest(1)方法輸出的結(jié)果如下:

123default
復(fù)制代碼

但是如果在某個(gè)case塊中加入break語(yǔ)句,那么這個(gè)case塊就不會(huì)被貫穿,如下:

public void switchTest(int a) {
 switch (a) {
 case 1: {
 System.out.print("1");
 break;
 }
 case 2: System.out.print("2");
 case 3: System.out.print("3");
 default: System.out.print("default");
 }
}
switchTest(1);
switchTest(2);
復(fù)制代碼

上面的代碼中執(zhí)行switchTest(1)輸出結(jié)果為:

1
復(fù)制代碼

可見(jiàn)加入break之后沒(méi)有被貫穿,

而執(zhí)行switchTest(2)輸出結(jié)果為:

23default
復(fù)制代碼

關(guān)于break語(yǔ)句后面會(huì)有詳細(xì)的介紹

我對(duì)case代碼塊的理解。

其實(shí)case代碼塊和其他的代碼塊在本質(zhì)上是一樣的,它有自己的作用域,如下:

public static void main(String[] args) {
 int a = 1;
 switch(a) {
 case 1: {
 int b = 1;
 System.out.println(b);
 }
 case 2: {
 int b = 2;
 System.out.println(b);
 }
 }
 }
復(fù)制代碼

上述main方法執(zhí)行的結(jié)果是

1
2
復(fù)制代碼

case代碼塊和如下的代碼塊本質(zhì)上是一樣的:

//普通的代碼塊,使用的主要目的就是創(chuàng)建一個(gè)單獨(dú)的詞法作用域
{
	int a = 3;
 System.out.println(a);
}
//帶標(biāo)簽的代碼塊,除了能夠創(chuàng)建一個(gè)單獨(dú)的詞法作用域,還能夠使用break進(jìn)行一定的流程控制
labelName: {
 int a = 3;
 System.out.println(a);
}
復(fù)制代碼

而case代碼塊不同的地方在于,case代碼塊只能出現(xiàn)在switch語(yǔ)句中,并且其后面跟著一個(gè)跟switch中的表達(dá)式的值的類型相同的常量表達(dá)式,其實(shí)case的作用就是聲明了一個(gè)個(gè)的錨點(diǎn),能夠跟switch后的表達(dá)式的值匹配的哪個(gè)case錨點(diǎn)就是switch程序開(kāi)始執(zhí)行的地方,這也就解釋了switch的貫穿

基本上所有擁有switch語(yǔ)句的語(yǔ)言中,case的作用大都是相同的,同時(shí)switch也都具有貫穿的特性。

循環(huán)結(jié)構(gòu)

循環(huán)語(yǔ)句可以在滿足循環(huán)條件的情況下,反復(fù)執(zhí)行某一段代碼,這段被重復(fù)執(zhí)行的代碼被稱為循環(huán)體。循環(huán)語(yǔ)句可能包含如下四個(gè)部分

  • 初始化語(yǔ)句(init_statement):一條或者多條語(yǔ)句,這些語(yǔ)句用于完成一些初始化工作,初始化語(yǔ)句在循環(huán)體開(kāi)始執(zhí)行之前執(zhí)行。
  • 循環(huán)條件(test_expression):這個(gè)測(cè)試表達(dá)式的值必須是boolean類型的,這個(gè)表達(dá)式?jīng)Q定是否繼續(xù)執(zhí)行循環(huán)體
  • 循環(huán)體(loop_statement):這個(gè)部分是循環(huán)的主體,如果循環(huán)條件成立,這個(gè)代碼塊將被一直執(zhí)行。
  • 迭代語(yǔ)句(iteration_statement):這個(gè)部分在每一次循環(huán)體結(jié)束之后,在對(duì)測(cè)試表達(dá)式求值之前執(zhí)行,通常用于改變循環(huán)條件相關(guān)的變量,使得循環(huán)在合適的時(shí)候結(jié)束。

上面的四個(gè)部分只是一般性的分類,并不是每個(gè)循環(huán)中都非常明確的分出了這4個(gè)部分。

直到型循環(huán)結(jié)構(gòu)

直到型循環(huán)結(jié)構(gòu)的特點(diǎn)就是循環(huán)體會(huì)無(wú)條件的執(zhí)行一次,在Java中提供了do while語(yǔ)句對(duì)直到型循環(huán)提供了支持。

do while語(yǔ)句

do while循環(huán)的結(jié)構(gòu)如下:

init_statement
do {
	loop_statement
	iteration_statement
	[break/continue] //[]代表可選的
} while(test_expression); //不要忘記末尾的分號(hào)
復(fù)制代碼

需要注意的是,iteration_statement和loop_statement之間并沒(méi)有明確的順序關(guān)系,但是我們需要注意的是,iteration_statement應(yīng)該位于continue語(yǔ)句之前,否則會(huì)容易造成死循環(huán),如下:

public static void main(String[] args) {
 int i = 0;
 do {
 System.out.println(i);
 if (i%3 == 1)
 continue;
 i++;
 } while (i < 9);
}
復(fù)制代碼

運(yùn)行上面的main方法將會(huì)產(chǎn)生死循環(huán)。所以迭代語(yǔ)句應(yīng)該放在continue語(yǔ)句之前

當(dāng)型循環(huán)結(jié)構(gòu)

當(dāng)型循環(huán)結(jié)構(gòu)的特點(diǎn)就是,在執(zhí)行循環(huán)體之前就進(jìn)行循環(huán)條件的檢測(cè),如果循環(huán)條件在剛開(kāi)始就不滿足,那么循環(huán)體一次都不會(huì)執(zhí)行。

Java提供了while語(yǔ)句和for語(yǔ)句對(duì)當(dāng)型循環(huán)結(jié)構(gòu)提供支持

while語(yǔ)句

while循環(huán)的語(yǔ)法格式如下:

[init statement]
while(test_expression) {
	loop_statement
	[iteration_statement]
	[break/continue] //跟do類似的是,如果存在迭代語(yǔ)句,要放在continue語(yǔ)句之前,防止造成死循環(huán)
}
復(fù)制代碼

for語(yǔ)句

for循環(huán)是最簡(jiǎn)潔的一種循環(huán)語(yǔ)句,同時(shí)其寫法也是最為靈活的,它把循環(huán)體獨(dú)立出來(lái),同時(shí)固定了迭代語(yǔ)句和測(cè)試表達(dá)式的執(zhí)行順序,for語(yǔ)句的基本格式如下:

for ([init_statement]; [test_statement], [iteration_statement]) {
 loop_statement
}
復(fù)制代碼

可以看到,for語(yǔ)句匯總的init_statement、test_statement和iteration_statement都是可選的,這就意味著for循環(huán)可以完全取代while循環(huán),for循環(huán)是使用頻率最高的循環(huán)語(yǔ)句,原因如下:

  • 在for循環(huán)的初始化語(yǔ)句中聲明的變量其作用于可以限制在for循環(huán)的語(yǔ)句體之內(nèi)。
  • for循環(huán)的迭代語(yǔ)句沒(méi)有與循環(huán)體放在一起,因此即使是在執(zhí)行循環(huán)體的時(shí)候遇到了continue語(yǔ)句提前結(jié)束本次循環(huán),迭代語(yǔ)句也會(huì)得到執(zhí)行。

雖然for循環(huán)的寫法比較自由,但是我們?cè)谑褂胒or循環(huán)的時(shí)候盡量采用標(biāo)準(zhǔn)的寫法,這樣可以充分利用for循環(huán)的特性,同時(shí)提高代碼的可讀性,所以這里就不介紹關(guān)于for循環(huán)的騷操作了。

增強(qiáng)的for語(yǔ)句

Java5中,為Iterable和數(shù)組類型新增了增強(qiáng)的for語(yǔ)句,其格式如下:

for ([variableModifier] Type variableDeclaratorId: Expression) {
 loop_statement
}
復(fù)制代碼

需要注意的是,上述Express的類型必須是Iterable或者是數(shù)組類型,否則會(huì)產(chǎn)生編譯錯(cuò)誤

增強(qiáng)的for循環(huán)只是一種語(yǔ)法糖,它在編譯器的解糖階段就會(huì)轉(zhuǎn)換成普通的for循環(huán),增強(qiáng)的for循環(huán)會(huì)按照如下規(guī)則轉(zhuǎn)譯為基本的for語(yǔ)句:

  • 如果Expression 的類型是 Iterable 的子類型,那么就按照如下方式進(jìn)行轉(zhuǎn)譯: 以如下代碼為例
List<String> nameList = Arrays.asList("zhangsan","lisi","wangwu");
//增強(qiáng)for循環(huán)
for(String name: nameList) {
 System.out.println(name);
}
//上述的增強(qiáng)的for循環(huán)就等價(jià)于如下的普通循環(huán)
for (Iterator<String> i = Expression.iterator(); i.hasNext(); ) {
 String name = i.next();
 System.out.println(name);
}
復(fù)制代碼
  • 否則, Expression必須具有數(shù)組類型,這時(shí)候其轉(zhuǎn)換方式如下: 以如下代碼為例:
String[] nameArr = new String[]{"zhangsan","lisi","wangwu"};
//增強(qiáng)的for循環(huán)
for(String name: nameArr) {
 System.out,println(name);
}
//上述的增強(qiáng)的for循環(huán)等價(jià)于如下的普通for循環(huán)
for (int i = 0; i< nameArr.length; i++) {
 String name = nameArr[i];
 System.out.println(name);
}
復(fù)制代碼

更精細(xì)的流程控制

分支和循環(huán)結(jié)構(gòu)只是為我們提供了基本的流程控制功能,但是在循環(huán)中有時(shí)候我們需要提前結(jié)束某次或者是整個(gè)循環(huán),又或者某段代碼在執(zhí)行到一定的流程的時(shí)候需要提前結(jié)束,這樣基本的流程控制是滿足不了的。

雖然Java中放棄了飽受詬病的goto語(yǔ)句,但是也為我們提供了一些對(duì)程序流程進(jìn)行更加精細(xì)控制的方式。

前面也對(duì)break語(yǔ)句和continue語(yǔ)句做過(guò)一些介紹了,下面進(jìn)行一下詳細(xì)的說(shuō)明。

break語(yǔ)句

break語(yǔ)句會(huì)將控制流程轉(zhuǎn)移到包含它的語(yǔ)句或者塊之外。它分為帶標(biāo)號(hào)和不帶標(biāo)號(hào)兩種情況。不帶標(biāo)號(hào)的 break語(yǔ)句只能用在循環(huán)結(jié)構(gòu)或者是switch語(yǔ)句之中,而帶標(biāo)號(hào)的 break可以使用在任何語(yǔ)句塊中

不帶標(biāo)簽的break語(yǔ)句

不帶標(biāo)號(hào)的break語(yǔ)句視圖將控制流轉(zhuǎn)移到包圍它的最內(nèi)層的switch、do、while或者for語(yǔ)句中(一定要注意這一點(diǎn),因?yàn)檫@四種語(yǔ)句之間可以相互嵌套或者是自嵌套)。這條語(yǔ)句被稱為break目標(biāo),然后立即正常結(jié)束。

如果該不帶標(biāo)號(hào)的break語(yǔ)句不被包含在任何switch、do、while或者for語(yǔ)句中,那么就會(huì)編譯失敗。

帶標(biāo)簽的break語(yǔ)句

在了解帶標(biāo)簽的break語(yǔ)句之前,我們先來(lái)了解一下什么是標(biāo)號(hào)語(yǔ)句

語(yǔ)句前可以有標(biāo)號(hào)前綴,如下:

label: {
 System.out.println("a1");
}
復(fù)制代碼

java編程語(yǔ)言沒(méi)有任何goto語(yǔ)句,標(biāo)識(shí)符語(yǔ)句標(biāo)號(hào)會(huì)用于出現(xiàn)在標(biāo)號(hào)語(yǔ)句內(nèi)的任何地方的break或者continue語(yǔ)句之上。

標(biāo)號(hào)本質(zhì)上其實(shí)也是一個(gè)標(biāo)識(shí)符,而這個(gè)標(biāo)識(shí)符的作用域就是其直接包含的語(yǔ)句的內(nèi)部,因?yàn)镴ava中規(guī)定,只能在該標(biāo)號(hào)所包含的語(yǔ)句之中才能引用這個(gè)標(biāo)號(hào)。,如下代碼說(shuō)明了標(biāo)號(hào)語(yǔ)句的標(biāo)號(hào)標(biāo)識(shí)符的作用域:

public class a {
 public static void main(String[] args) {
 a: {
 int a = 3;
 System.out.println("a1");
 }
		
 //這個(gè)地方編譯通過(guò), 說(shuō)明a的作用域并不是在main方法中,而是在它包含的語(yǔ)句之中
 a: {
 System.out.println("a2");
 }
 }
}
復(fù)制代碼

同時(shí),通過(guò)上面的代碼我們也可以看出,不同類型的標(biāo)識(shí)符之間是互不影響的(Java中的標(biāo)識(shí)符有類型名、變量名、標(biāo)號(hào)等等),即對(duì)于將相同的標(biāo)識(shí)符同時(shí)用做標(biāo)號(hào)和包名、類名、接口名、方法名、域名城、方法參數(shù)名、或者局部變量名這種做法,Java沒(méi)有做出任何限制

下面正式進(jìn)入帶標(biāo)號(hào)的break語(yǔ)句的講解

帶有標(biāo)號(hào)的break語(yǔ)句視圖將控制流轉(zhuǎn)移到將相同標(biāo)號(hào)作為其標(biāo)號(hào)的標(biāo)號(hào)語(yǔ)句,該語(yǔ)句稱為break目標(biāo)語(yǔ)句,然后立即結(jié)束。

在帶標(biāo)號(hào)的break語(yǔ)句中break目標(biāo)不必是switch、do、while或者for語(yǔ)句

需要注意的是,前面講到過(guò)標(biāo)號(hào)語(yǔ)句表標(biāo)號(hào)的作用范圍是在標(biāo)號(hào)語(yǔ)句的語(yǔ)句體內(nèi)部,所以被break的標(biāo)號(hào)語(yǔ)句必須包含break語(yǔ)句

前面的描述中稱“視圖轉(zhuǎn)移控制流程”而不是"直接轉(zhuǎn)移控制流程",是因?yàn)槿绻?break目標(biāo) 內(nèi)有任何try語(yǔ)句,其try子句或者catch子句包含break語(yǔ)句,那么在控制流程轉(zhuǎn)移到 break 目標(biāo)之前,這些 try語(yǔ)句的所有的 finally 子句會(huì)按照從最內(nèi)部到最外部的數(shù)學(xué)被執(zhí)行,而 finally 子句的猝然結(jié)束都會(huì)打斷break語(yǔ)句觸發(fā)的控制流轉(zhuǎn)移

continue語(yǔ)句

continue語(yǔ)句只能出現(xiàn)在while、do或者for語(yǔ)句匯總,這三種語(yǔ)句被稱為迭代語(yǔ)句。控制流會(huì)傳遞到迭代語(yǔ)句的循環(huán)持續(xù)點(diǎn)上。

continue語(yǔ)句也有代標(biāo)號(hào)和不帶標(biāo)號(hào)兩種使用方式,和break語(yǔ)句不同的是,continue語(yǔ)句的這兩種使用方式都只能出現(xiàn)在迭代語(yǔ)句中,下文進(jìn)行詳細(xì)的介紹

不帶標(biāo)簽的continue語(yǔ)句

不帶標(biāo)簽的continue試圖將控制流轉(zhuǎn)移到包圍它的最內(nèi)層的switch、do、while或者for語(yǔ)句中(一定要注意這一點(diǎn),因?yàn)檫@四種語(yǔ)句之間可以相互嵌套或者是自嵌套)。這條語(yǔ)句被稱為continue目標(biāo),然后立即結(jié)束當(dāng)前的迭代并進(jìn)行下一輪的迭代。

如果該不帶標(biāo)號(hào)的continue語(yǔ)句不被包含在任何switch、do、while或者for語(yǔ)句中,那么就會(huì)編譯失敗。

帶標(biāo)簽的continue語(yǔ)句

前面已經(jīng)對(duì)標(biāo)號(hào)進(jìn)行了介紹,下面我們直接進(jìn)入帶標(biāo)簽的continue語(yǔ)句的講解

帶標(biāo)號(hào)的continue語(yǔ)句視圖將控制流轉(zhuǎn)移到將相同標(biāo)號(hào)作為標(biāo)號(hào)的標(biāo)號(hào)語(yǔ)句,但是同時(shí),這個(gè)標(biāo)號(hào)語(yǔ)句必須是一個(gè)迭代語(yǔ)句,這條語(yǔ)句被稱為continue目標(biāo)然后理解結(jié)束當(dāng)前的迭代并進(jìn)行新一輪的迭代。

如果continue目標(biāo)不是一個(gè)迭代語(yǔ)句,那么就會(huì)產(chǎn)生一個(gè)編譯時(shí)錯(cuò)誤。

前面的描述中稱“視圖轉(zhuǎn)移控制流程”而不是"直接轉(zhuǎn)移控制流程",是因?yàn)槿绻?continue目標(biāo) 內(nèi)有任何try語(yǔ)句,其try子句或者catch子句包含continue語(yǔ)句,那么在控制流程轉(zhuǎn)移到 continue目標(biāo)之前,這些 try語(yǔ)句的所有的 finally 子句會(huì)按照從最內(nèi)部到最外部的數(shù)學(xué)被執(zhí)行,而 finally 子句的猝然結(jié)束都會(huì)打斷 continue 語(yǔ)句觸發(fā)的控制流轉(zhuǎn)移

其他語(yǔ)句

return 語(yǔ)句

return 語(yǔ)句會(huì)將控制流返回給方法或構(gòu)造器的調(diào)用者。return語(yǔ)句必須被包含在可執(zhí)行成員中(方法、構(gòu)造器、lambda表達(dá)式),return語(yǔ)句也分為兩種,一種是帶有返回值的,一種是不帶有返回值的。

需要注意的是,return語(yǔ)句觸發(fā)的流程轉(zhuǎn)移也是視圖轉(zhuǎn)移控制流,而不是直接轉(zhuǎn)移控制流,原因也是try的finally子句

對(duì)于return語(yǔ)句,我們不需要說(shuō)明太多。

throw 語(yǔ)句

throw語(yǔ)句會(huì)導(dǎo)致異常對(duì)象被拋出,這將會(huì)視圖將控制流程進(jìn)行轉(zhuǎn)移,有可能會(huì)退出多個(gè)語(yǔ)句和多個(gè)構(gòu)造器、實(shí)例初始化器、靜態(tài)初始化器和域初始化器的計(jì)算以及方法調(diào)用,知道找到可以捕獲拋出值的try語(yǔ)句。如果沒(méi)有這種try語(yǔ)句,那么執(zhí)行throw的線程的執(zhí)行會(huì)在該線程所屬的線程組上調(diào)用uncaughtException 方法后被終止。

上述也提到了視圖轉(zhuǎn)移控制流程,也是因?yàn)閠ry的finally子句,如下:

 try {
 throw new RuntimeException("故意拋出");
} finally {
 System.out.println("還是會(huì)執(zhí)行");
 throw new RuntimeException("finally中拋出");
}
復(fù)制代碼

但是上述的用法是基本不會(huì)出現(xiàn)的,因?yàn)樵谝粋€(gè)執(zhí)行體中拋出異常就是為了給調(diào)用這個(gè)執(zhí)行體的上層執(zhí)行體提供一種提示,并期望調(diào)用者能夠處理這種異常。

關(guān)于異常會(huì)在后面進(jìn)行更加詳細(xì)的說(shuō)明。

synchronized 語(yǔ)句

這涉及到了多線程編程,以后會(huì)進(jìn)行專門的介紹。

try 語(yǔ)句

try語(yǔ)句會(huì)執(zhí)行一個(gè)語(yǔ)句塊。**如果拋出了值并且try語(yǔ)句有一個(gè)或者多個(gè)可以捕獲它的catch子句,那么控制流就會(huì)轉(zhuǎn)移到第一個(gè)這種catch子句上。**這一點(diǎn)在后面講異常處理的時(shí)候也會(huì)講到。

如果try語(yǔ)句有finally子句,那么將會(huì)執(zhí)行另一個(gè)代碼塊,無(wú)論try塊是正常結(jié)束還是猝然結(jié)束,并且無(wú)論控制流之前是否轉(zhuǎn)移到某個(gè)catch塊上。

try語(yǔ)句的格式如下所示,有三種形式:

// try-catch
try {
 statement
} catch(Type1 | Type2... e) {
 statement
}
//try-finally
try {
 statement
} finally {
 statement
}
//try-catch-finally
try {
 statement
} catch (Type1 | Type2... e) {
 statement
} finally {
 statement
}
復(fù)制代碼

在try語(yǔ)句后緊跟的語(yǔ)句塊我們稱之為try語(yǔ)句的try塊

在finally關(guān)鍵字之后緊跟的語(yǔ)句塊我們稱之為finally塊

try語(yǔ)句的catch子句通常被稱為異常處理器。catch子句有且僅有一個(gè)參數(shù),被稱為異常參數(shù),異常參數(shù)可以將它的類型表示成單一的類類型,或者表示成兩個(gè)或者更多類型的聯(lián)合體(這些類型稱為可選項(xiàng)),聯(lián)合體中的可選項(xiàng)在語(yǔ)法上使用|進(jìn)行分割

需要注意的是,當(dāng)catch子句的異常參數(shù)的類型是一個(gè)類型聯(lián)合體的時(shí)候,這個(gè)異常參數(shù)就一定是final類型的,要么是隱式的,當(dāng)然也可以顯示聲明為final的,但是這時(shí)候應(yīng)該講類型聯(lián)合體看做是一個(gè)類型,final修飾符只需要書寫一次就可以了。如下:

try {
 throw new RuntimeException();
} catch (final UnsupportedOperationException | NullPointerException e) { //final修飾符只需在類型聯(lián)合體前面書寫一次就可以了,這時(shí)候要把類型聯(lián)合體看做一個(gè)類型
 System.out.println("是可以改變的!");
}
復(fù)制代碼

這是因?yàn)閏atch類型處理器完全依賴于try塊中拋出的異常的類型。而使用了類型聯(lián)合體之后,異常參數(shù)的類型就只能在運(yùn)行時(shí)才能確定,所以必須是final的,在被捕獲的時(shí)候初始化一次。

同時(shí)我們上面也提到過(guò)一句話,**如果拋出了值并且try語(yǔ)句有一個(gè)或者多個(gè)可以捕獲它的catch子句,那么控制流就會(huì)轉(zhuǎn)移到第一個(gè)這種catch子句上。**這就提醒我們?cè)谑褂胏atch子句的時(shí)候需要注意,要把子類類型放在前面進(jìn)行捕獲,否則就會(huì)被父類類型的異常處理器攔截。同時(shí),在catch子句中使用類型聯(lián)合體的時(shí)候,類型聯(lián)合體中的各個(gè)可選項(xiàng)之間不能具有任何的父子關(guān)系。

try語(yǔ)句的執(zhí)行流程沒(méi)有什么好說(shuō)的,我們只需要記住一點(diǎn),finally子句肯定會(huì)被執(zhí)行

帶資源的 try 語(yǔ)句

帶資源的try語(yǔ)句是用變量(被稱為資源)來(lái)參數(shù)化的,這些資源在try塊執(zhí)行之前被初始化,并且在try塊執(zhí)行之后,自動(dòng)地以與初始化相反的順序被關(guān)閉。當(dāng)資源會(huì)被自動(dòng)關(guān)閉的時(shí)候,catch子句和finally子句經(jīng)常不是必須的。

關(guān)于資源,我們需要注意以下幾點(diǎn):

  • try中的資源變量肯定是final的,如果不顯式聲明為final,則會(huì)被隱式聲明為final,這是因?yàn)樾枰獙?duì)聲明的資源進(jìn)行自動(dòng)關(guān)閉,所以不允許修改資源變量的指向。
  • 在帶資源的try語(yǔ)句中聲明的資源必須是AutoCloseable的子類型,否則會(huì)產(chǎn)生編譯錯(cuò)誤。
  • 資源是按照從左到右的順序被初始化的。如果某個(gè)資源初始化失敗了(即初始化表達(dá)式拋出了異常),那么所有已經(jīng)完成了初始化的資源都將被關(guān)閉。如果所有的資源都初始化成功了,那么try塊就會(huì)正常執(zhí)行,然后帶資源的try語(yǔ)句的所有非null資源都將被關(guān)閉。
  • 資源將以它們被初始化的順序相反的順序被關(guān)閉。資源只有在它們被初始化為非null值的時(shí)候才會(huì)被關(guān)閉。在關(guān)閉資源時(shí)拋出的異常不會(huì)阻止其他資源的關(guān)閉,其實(shí)最終帶資源的try語(yǔ)句都會(huì)被轉(zhuǎn)化為try-finally語(yǔ)句

不可達(dá)語(yǔ)句

如果某條語(yǔ)句因?yàn)樗遣豢蛇_(dá)的而不能被執(zhí)行,那么就是一個(gè)編譯時(shí)錯(cuò)誤。我們只需知道這種語(yǔ)句的存在,在不可達(dá)表現(xiàn)的非常明顯的時(shí)候IDE就會(huì)給出提示,但是有時(shí)候會(huì)有錯(cuò)誤的邏輯造成的不可達(dá)語(yǔ)句,就需要我們自己對(duì)代碼的結(jié)構(gòu)進(jìn)行分析了。

總結(jié)

以上就是我對(duì)Java中的表達(dá)式和操作符的理解和介紹,如有不當(dāng)之處,歡迎進(jìn)行指正。

分享到:
標(biāo)簽:操作 Java
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定