java編程相關總結(二)
java編程相關總結是一個持續更新的系列,是本人對自己多年工作中使用到java的一個經驗性總結,也是溫故而知新吧,因為很多基礎的東西過了這麼多年,平時工作中用不到也會遺忘掉,所以看看書,上上網,查查資料,也算是記錄下自己的筆記吧,過一段時間之後再來看看也是蠻不錯的,也希望能協助到正在學習的人們,本系列將要總結一下幾點: 物件導向的編程思想 java的基本文法 一些有趣的架構解析 實戰項目的整體思路 代碼的最佳化以及效能調優的幾種方案 其它遺漏的東西以及補充 java的基本文法
結合上一節,我們也從最基本的類開始,首先是經典的hello word案例:
package com.klsstt.helloword; public class HelloWord{ public static void main(String [] args){ System.out.println("Hello Word !"); } }
這個案例輸出了“Hello Word !”,其中,關鍵字class,用來建立類,public則是存取修飾詞,代表這個類的存取權限,HelloWord則是這個類的名稱,一般類的命名都是首字母大寫的駝峰命名法。package是包的聲明,表明當前類的包路徑,static關鍵字代表該方法是靜態方法,main則是方法名稱,main方法是java程式預設產生的可執行檔方法。 大小寫敏感性
Java 是一種大小寫敏感的語言,這就意味著 Hello 和 hello 在 Java 中代表不同的意思。
Java 關鍵字總是小寫
避免使用只有大小寫不同的變數名。 類的命名
所有類的名稱首字母必須大寫。
始終確保在您的代碼和Java檔案名稱相匹配的類名。
如果類名稱中包含幾個單詞,那麼每個單詞的首字母都要大寫。
例如類 HelloWord Java 標識符
標識符就是用於給 Java 程式中變數、類、方法等命名的符號。
使用標識符時,需要遵守幾條規則:
標識符可以由字母、數字、底線(_)、美元符($)組成,但不能包含 @、%、空格等其它特殊字元,不能以數字開頭。如:123name
標識符不能是 Java 關鍵字和保留字( Java 預留的關鍵字,以後的升級版本中有可能作為關鍵字),但可以包含關鍵字和保留字。如:不可以使用 void 作為標識符,但是 Myvoid 可以。 標識符是嚴格區分大小寫。 一定要分清楚Hello 和 hello 是兩個不同的標識符哦。 標識符的命名最好能反映出其作用,做到見名知意。 Java 修飾符
存取修飾詞:default, public , protected, private
非存取修飾詞:final, abstract, strictfp Java 關鍵字列表
存取控制:
private 私人的
protected 受保護的
public 公用的
類、方法和變數修飾符:
abstract 聲明抽象
class 類
extends 擴允,繼承
final 終極,不可改變的
implements 實現
interface 介面
native 本地
new 建立
static 靜態
strictfp 嚴格,精準
synchronized 線程,同步
transient 短暫
volatile 易失
程式控制語句:
break 跳出迴圈
continue 繼續
return 返回
do 運行
while 迴圈
if 如果
else 反之
for 迴圈
instanceof 執行個體
switch 開關
case 返回開關裡的結果
default 預設
錯誤處理:
try 捕獲異常
catch 處理異常
finally 有沒有異常都執行
throw 拋出一個異常對象
throws 聲明一個異常可能被拋出
assert 斷言
包相關:
import 引入
package 包
基本類型:
boolean 布爾型
byte 位元組型
char 字元型
double 雙精確度,
float 浮點
int 整型
long 長整型
short 短整型
null 空
true 真
false 假
enum 枚舉
變數引用:
super 父類,超類
this 本類
void 無傳回值
關鍵字(51)+保留字(const,goto)共53個 Java 變數和常量
在程式中存在大量的資料來代表程式的狀態,其中有些資料在程式的運行過程中值會發生改變,有些資料在程式運行過程中值不能發生改變,這些資料在程式中分別被叫做變數和常量。
在實際的程式中,可以根據資料在程式運行中是否發生改變,來選擇應該是使用變數代表還是常量代表。
變數
變數代表程式的狀態。程式通過改變變數的值來改變整個程式的狀態,或者說得更大一些,也就是實現程式的功能邏輯。
為了方便的引用變數的值,在程式中需要為變數設定一個名稱,這就是變數名。
例如在2D遊戲程式中,需要代表人物的位置,則需要2個變數,一個是x座標,一個是y座標,在程式運行過程中,這兩個變數的值會發生改變。
由於Java語言是一種強型別的語言,所以變數在使用以前必須首先聲明,在程式中聲明變數的文法格式如下:
資料類型 變數名稱;
例如:int x;
在該文法格式中,資料類型可以是Java語言中任意的類型,包括前面介紹到的基礎資料型別 (Elementary Data Type)以及後續將要介紹的複合資料型別。變數名稱是該變數的標識符,需要符合標識符的命名規則,在實際使用中,該名稱一般和變數的用途對應,這樣便於程式的閱讀。資料類型和變數名稱之間使用空格進行間隔,空格的個數不限,但是至少需要1個。語句使用“;”作為結束。
也可以在聲明變數的同時,設定該變數的值,文法格式如下:
資料類型 變數名稱 = 值;
例如:int x = 10;
在該文法格式中,前面的文法和上面介紹的內容一致,後續的“=”代表賦值,其中的“值”代表具體的資料,注意區別“==”代表為判斷是否相等。在該文法格式中,要求值的類型需要和聲明變數的資料類型一致。
在程式中,變數的值代表程式的狀態,在程式中可以通過變數名稱來引用變數中儲存的值,也可以為變數重新賦值。例如:
int n = 5;
n = 10;
在實際開發過程中,需要聲明什麼類型的變數,需要聲明多少個變數,需要為變數賦什麼數值,都根據程式邏輯決定,這裡列舉的只是表達的格式而已。
常量
常量代表程式運行過程中不能改變的值。
常量在程式運行過程中主要有2個作用:
1. 代表常數,便於程式的修改(例如:圓周率的值)
2. 增強程式的可讀性(例如:常量UP、DOWN、LEFT和RIGHT分辨代表上下左右,其數值分別是1、2、3和4)
常量的文法格式和變數類型,只需要在變數的文法格式前面添加關鍵字final即可。在Java編碼規範中,要求常量名必須大寫。
則常量的文法格式如下:
final 資料類型 常量名稱 = 值;
final 資料類型 常量名稱1 = 值1, 常量名稱2 = 值2,……常量名稱n = 值n;
例如:
final double PI = 3.14;
final char MALE=‘M’,FEMALE=‘F’;
在Java文法中,常量也可以首先聲明,然後再進行賦值,但是只能賦值一次,範例程式碼如下:
final int UP;
UP = 1; 關於final詳解
final 用於聲明屬性(常量),方法和類,分別表示屬性一旦被分配記憶體空間就必須初始化(不會有預設初始化,局部變數也是如此,預設初始化只有普通的非final成員屬性,對於static(無final修飾)類變數,類串連時候有預設初始化,對於像private int a;在類執行個體化時,建構函式預設初始為0,總之,變數必須初始化後方可用,這是java的安全之一。
final這個關鍵字的含義是“這是無法改變的”或者“終態的”。
那麼為什麼要阻止改變呢。
java語言的發明者可能由於兩個目的而阻止改變:
1. 效率問題:
jdk中的某些類的某些方法,是不允許被使用者覆蓋的,設計者可能認為,所用方法已經是最好的方法,使用者私自覆蓋,或是由於疏忽而覆蓋,就會影響JVM或是系統的系能;
2. 設計所需:
眾所周知,有些情況必須使用final關鍵字,比如方法中的匿名內部類的參數傳遞
【修飾變數】:
final成員變數表示常量,只能被賦值一次,賦值後值不再改變。
【修飾方法】:
final方法不能被子類方法覆蓋,但可以被繼承。
【修飾類】:
final類不能被繼承,沒有子類,final類中所有方法都是final的。(如String類)
被final修飾而沒有被static修飾的類的屬性變數只能在兩種情況下初始化(必須初始化):
a.在它被聲明的時候賦值
b.在建構函式裡初始化
解釋: 當這個屬性被修飾為final,而非static的時候,它屬於類的執行個體對象的資源(執行個體常量),當類被載入進記憶體的時候這個屬性並沒有給其分配記憶體空間,而只是 定義了一個變數a,只有當類被執行個體化的時候這個屬性才被分配記憶體空間,而執行個體化的時候同時執行了建構函式,所以屬性被初始化了,也就符合了當它被分配記憶體 空間的時候就需要初始化,以後不再改變的條件.
被static修飾而沒有被final修飾的類的屬性變數只能在兩種情況下初始化(可以不初始化):
a.在它被聲明的時候賦值
b.在靜態或非靜態快裡初始化
解釋:
當類的屬性被同時被修飾為static時候,他屬於類的資源(類變數),在類載入後,進行串連時候,分三步: 先驗證;然後準備,準備時,先分配記憶體,接著預設初始化;可以進行解析。最後,進行類初始化,類初始化前,必須保證它的父類已經初始化了,所以最先初始化的是超類,對於介面,不必初始其父介面。類初始化時,它把類變數初始化語句及靜態初始化語句放到類初始化方法中,所以,如果無此兩種語句,也就沒類初始化方法,而建構函式是在當類 被執行個體化的時候才會執行,所以用建構函式,這時候這個屬性沒有被初始化.程式就會報錯.而static塊是類被載入的時候執行,且只執行這一次,所以在 static塊中可以被初始化.
同時被final和static修飾的類的屬性變數只能在兩種情況下初始化(必須初始化):
a.在它被定義的時候
b.在類的靜態塊裡初始化
c.特別對於初始化時候調用拋出異常的建構函式,初始時候注意,特別是在實現單例模式時(只能這麼初始化)
如:
class A{ private final static A a; static{ try{ a=new A(); }catch(Exception e){ throws new RuntimeException(e); //必須有,不然不能完成常量的正確初始化 } } private A() throws Exception{}}
解釋:
當類的屬性被同時被修飾為static和final的時候,他屬於類的資源(類常量),那麼就是類在被載入進記憶體的時候(也就是應用程 序啟動的時候)就要已經為此屬性分配了記憶體,所以此時屬性已經存在,它又被final修飾,所以必須在屬性定義了以後就給其初始化值.而建構函式是在當類 被執行個體化的時候才會執行,所以用建構函式,這時候這個屬性沒有被初始化.程式就會報錯.而static塊是類被載入的時候執行,且只執行這一次,所以在 static塊中可以被初始化.
java中的 final變數==常量
【final變數的變與不變】:final表示變數的值或引用不變
有人說final變數在賦值後就不可變,此變數可以是基礎資料型別 (Elementary Data Type)+String或者是對象
那麼這個不變到底指的是什麼呢。
這個不變指的是引用,是地址,而所引用的對象的內容仍然是可變的。
註:如果為對象,注意此時類初始化條件
就是說,這個final變數永遠指向某個對象,是一個常量指標,而不是指向常量的指標。
【final關鍵字的具體應用】:
【final+變數】:
在實際應用中,這種形式是非常少見的。
比如logger是可以的,但是貌似並不是非常實用,或許使用者仍然希望通過setter來改變logger變數。
【static+final+變數】:
常量,經常使用。
【final+方法】:
JDK中常用,但是自己並未常用。
【final+類】:
helper類經常使用。
【final用於匿名內部類的參數傳遞】:
在多線程測試時,經常使用。
【final用於方法的參數】:
並不常用。 Java 數組
數組時儲存有多重相同變數類型的對象。然而,數字自身也是堆中的一個對象。我們將要學習如何聲明,建立,初始化數組。
定義數組
1. (推薦,更能表明數群組類型)
type[] 變數名 = new type[數組中元素的個數];
比如:
int[] a = new int[10];
數組名,也即引用a,指向數組元素的首地址。
2. (同C語言)
type變數名[] = new type[數組中元素的個數];
如:
int a[] = new int[10];
3. 定義時直接初始化
type[] 變數名 = new type[]{逗號分隔的初始化值};
其中紅色部分可省略,所以又有兩種:
int[] a = {1,2,3,4};
int[] a = new int[]{1,2,3,4};
其中int[] a = new int[]{1,2,3,4};的第二個方括弧中不能加上數組長度,因為元素個數是由後面花括弧的內容決定的。
數組運用基礎
數組長度
Java中的每個數組都有一個名為length的屬性,表示數組的長度。
length屬性是public final int的,即length是唯讀。數組長度一旦確定,就不能改變大小。
二維數組
二維數組是數組的數組。
基本的定義方式有兩種形式,如:
type[][] i = new type[2][3];(推薦)
type i[][] = new type[2][3];
變長的二維數組
二維數組的每個元素都是一個一維數組,這些數組不一定都是等長的。
聲明二維數組的時候可以只指定第一維大小,空缺出第二維大小,之後再指定不同長度的數組。但是注意,第一維大小不能空缺(不能只指定列數不指定行數)。
二維數組也可以在定義的時候初始化,使用花括弧的嵌套完成,這時候不指定兩個維數的大小,並且根據初始化值的個數不同,可以產生不同長度的數組元素。 Java 集合
集合類說明及區別
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap Collection介面
Collection是最基本的集合介面,一個Collection代表一組Object,即Collection的元素(Elements)。一些 Collection允許相同的元素而另一些不行,一些能排序而另一些不行。
Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子介面”如List和Set。所有實現Collection介面的類都必須提供兩個標準的建構函式:無參數的建構函式用於建立一個空的Collection,有一個 Collection參數的建構函式用於建立一個新的Collection,這個新的Collection與傳入的Collection有相同的元素。後 一個建構函式允許使用者複製一個Collection。
如何遍曆Collection中的每一個元素。不論Collection的實際類型如何,它都支援一個iterator()的方法,該方法返回一個迭代子,使用該迭代子即可逐一訪問Collection中每一個元素。典型的用法如下:
Iterator it = collection.iterator(); // 獲得一個迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一個元素
}
由Collection介面派生的兩個介面是List和Set。 List介面
List是有序的Collection,使用此介面能夠精確的控制每個元素插入的位置。使用者能夠使用索引(元素在List中的位置,類似於數組下標)來訪問List中的元素,這類似於Java的數組。
和下面要提到的Set不同,List允許有相同的元素。
除了具有Collection介面必備的iterator()方法外,List還提供一個listIterator()方法,返回一個 ListIterator介面,和標準的Iterator介面相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設定元素, 還能向前或向後遍曆。
實現List介面的常用類有LinkedList,ArrayList,Vector和Stack。 LinkedList類
LinkedList實現了List介面,允許null元素。此外LinkedList提供額外的get,remove,insert方法在 LinkedList的首部或尾部。
這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque)。
注意LinkedList沒有同步方法。如果多個線程同時訪問一個List,則必須自己實現訪問同步。一種解決方案>是在建立List時構造一個同步的List:
List list = Collections.synchronizedList(new LinkedList(…)); ArrayList類
ArrayList實現了可變大小的數組。它允許所有元素,包括null。ArrayList沒有同步。
size,isEmpty,get,set方法已耗用時間為常數。但是add方法開銷為分攤的常數,
添加n個元素需要O(n)的時間。其他的方法已耗用時間為線性。
每個ArrayList執行個體都有一個容量(Capacity),即用於儲存元素的數組的大小。這個容量可隨著不斷>添加新元素而自動增加,但是增長演算法 並沒有定義。當需要插入大量元素時,在插入前可以調用>ensureCapacity方法來增加ArrayList的容量以提高插入效率。
和LinkedList一樣,ArrayList也是非同步的(unsynchronized)。 Vector類
Vector非常類似ArrayList,但是Vector是同步的。由Vector建立的Iterator,雖然和 ArrayList建立的Iterator是同一介面,但是,因為Vector是同步的,當一個Iterator被建立而且正在被使用,另一個線程改變了 Vector的狀態(例如,添加或刪除了一些元素),這時調用Iterator的方法時將拋出 ConcurrentModificationException,因此必須捕獲該異常。
- Stack 類
Stack繼承自Vector,實現一個後進先出的堆棧。Stack提供5個額外的方法使得Vector得以被當作堆棧使用。基本的push和pop 方法,還有peek方法得到棧頂的元素,empty方法測試堆棧是否為空白,search方法檢測一個元素在堆棧中的位置。Stack剛建立後是空棧。 Set介面
Set是一種不包含重複的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。
很明顯,Set的建構函式有一個約束條件,傳入的Collection參數不能包含重複的元素。
請注意:必須小心操作可變對象(Mutable Object)。如果一個Set中的可變元素改變了自身狀態導致Object.equals(Object)=true將導致一些問題。
- Map介面
請注意,Map沒有繼承Collection介面,Map提供key到value的映射。一個Map中不能包含相同的key,每個key只能映射一個 value。Map介面提供3種集合的視圖,Map的內容可以被當作一組key集合,一組value集合,或者一組key-value映射。 Hashtable類
Hashtable繼承Map介面,實現一個key-value映射的雜湊表。
通常預設的load factor 0.75較好地實現了時間和空間的均衡。
增大load factor可以節省空間的但相應的尋找時間將增大,這會影響像get和put這樣的操作。
使用Hashtable的簡單樣本如下,將1,2,3放到Hashtable中,他們的key分是”one”,”two”,”three”:
Hashtable numbers = new Hashtable(); numbers.put(“one”, new Integer(1)); numbers.put(“two”, new Integer(2)); numbers.put(“three”, new Integer(3));
要取出一個數,比如2,用相應的key:
Integer n = (Integer)numbers.get(“two”); System.out.println(“two = ” + n);
由於作為key的對象將通過計算其散列函數來確定與之對應的value的位置,因此任何作為key的對象都必須實現hashCode和equals方 法。
hashCode和equals方法繼承自根類Object,如果你用自訂的類當作key的話,要相當小心,按照散列函數的定義,如果兩個對象相 同,即obj1.equals(obj2)=true,則它們的hashCode必須相同,但如果兩個對象不同,則它們的hashCode不一定不同,如 果兩個不同對象的hashCode相同,這種現象稱為衝突,衝突會導致操作雜湊表的時間開銷增大,所以盡量定義好的hashCode()方法,能加快雜湊 表的操作。
如果相同的對象有不同的hashCode,對雜湊表的操作會出現意想不到的結果(期待的get方法返回null),要避免這種問題,只需要牢記一條:要同時複寫equals方法和hashCode方法,而不要唯寫其中一個。
Hashtable是同步的。 HashMap類
HashMap和Hashtable類似,不同之處在於HashMap是非同步的,並且允許null,即null value和null key。,但是將HashMap視為Collection時(values()方法可返回Collection),其迭代子操作時間開銷和HashMap 的容量成比例。因此,如果迭代操作的效能相當重要的話,不要將HashMap的初始化容量設得過高,或者load factor過低。 WeakHashMap類
WeakHashMap是一種改進的HashMap,它對key實行“弱引用”,如果一個key不再被外部所引用,那麼該key可以被GC回收。
總結
如果涉及到堆棧,隊列等操作,應該考慮用List,對於需要快速插入,刪除元素,應該使用LinkedList,如果需要快速隨機訪問元素,應該使用ArrayList。
如果程式在單線程環境中,或者訪問僅僅在一個線程中進行,考慮非同步的類,其效率較高,如果多個線程可能同時操作一個類,應該使用同步的類。
要特別注意對雜湊表的操作,作為key的對象要正確複寫equals和hashCode方法。
盡量返回介面而非實際的類型,如返回List而非ArrayList,這樣如果以後需要將ArrayList換成LinkedList時,用戶端代碼不用改變。這就是針對抽象編程。
同步性
Vector是同步的。這個類中的一些方法保證了Vector中的對象是安全執行緒的。而ArrayList則是非同步,因此ArrayList中的對象並 不是安全執行緒的。因為同步的要求會影響執行的效率,所以如果你不需要安全執行緒的集合那麼使用ArrayList是一個很好的選擇,這樣可以避免由於同步帶 來的不必要的效能開銷。
資料增長
從內部實現機制來講ArrayList和Vector都是使用數組(Array)來控制集合中的對象。當你向這兩種類型中增加元素的時候,如果元素的數目 超出了內部數組目前的長度它們都需要擴充內部數組的長度,Vector預設情況下自動成長原來一倍的數組長度,ArrayList是原來的50%,所以最 後你獲得的這個集合所佔的空間總是比你實際需要的要大。所以如果你要在集合中儲存大量的資料那麼使用Vector有一些優勢,因為你可以通過設定集合的初 始化大小來避免不必要的資源開銷。
使用模式
在ArrayList和Vector中,從一個指定的位置(通過索引)尋找資料或是在集合的末尾增加、移除一個元素所花費的時間是一樣的,這個時間我們用 O(1)表示。但是,如果在集合的其他位置增加或移除元素那麼花費的時間會呈線形增長:O(n-i),其中n代表集合中元素的個數,i代表元素增加或移除 元素的索引位置。
為什麼會這樣呢。以為在進行上述操作的時候集合中第i和第i個元素之後的所有元素都要執行位移的操作。
這一切意味著什麼呢。
這意味著,你只是尋找特定位置的元素或只在集合的末端增加、移除元素,那麼使用Vector或ArrayList都可以。如果是其他動作,你最好選擇其他 的集合操作類。比如,LinkList集合類在增加或移除集合中任何位置的元素所花費的時間都是一樣的?O(1),但它在索引一個元素的使用缺比較慢 -O(i),其中i是索引的位置.使用ArrayList也很容易,因為你可以簡單的使用索引來代替建立iterator對象的操作。LinkList也 會為每個插入的元素建立對象,所有你要明白它也會帶來額外的開銷。
最後,在《Practical Java》一書中Peter Haggar建議使用一個簡單的數組(Array)來代替Vector或ArrayList。尤其是對於執行效率要求高的程式更應如此。因為使用數組 (Array)避免了同步、額外的方法調用和不必要的重新分配空間的操作。 Java 枚舉值
枚舉是在 Java5.0 版本中被引進的。枚舉限制了變數要有一些預先定義的值。枚舉列表中的值稱為枚舉值。
運用枚舉值可以大大減少你的代碼中的漏洞。
舉例來說,如果我們想為一家鮮榨果汁店編個程式,就可以將杯子的尺寸限制為小中和大。這樣就可以確保人們不會定大中小尺寸之外
class FreshJuice { enum FreshJuiceSize{ SMALL, MEDIUM, LARGE } FreshJuiceSize size;}public class FreshJuiceTest { public static void main(String args[]){ FreshJuice juice = new FreshJuice(); juice.size = FreshJuice. FreshJuiceSize.MEDIUM ; System.out.println("Size: " + juice.size); }}
輸出如下結果:Size: MEDIUM
註:枚舉可以自己聲明也可以在類中聲明。方法變數和構造器也可以在枚舉值中定義。 Java 中的注釋
Java支援單行或多行注釋,所有注釋中的字母都會被 Java 編譯器忽略。
行注釋:
//開始
塊注釋:
/*開始
* /結束
javadoc注釋:產生javadoc時,這樣的注釋會被產生標準的javaapi注釋,該注釋可以跨多行
/**
*
*/ Java 中的分支語句 break語句
break語句有兩種形式:標籤和非標籤。在前面的switch語句,看到的break語句就是非標籤形式。可以使用非標籤break,結束for,while,do-while迴圈,如下面的BreakDemo程式:
class BreakDemo { public static void main(String[] args) { int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076, 2000, 8, 622, 127 }; int searchfor = 12; int i; boolean foundIt = false; for (i = 0; i < arrayOfInts.length; i++) { if (arrayOfInts[i] == searchfor) { foundIt = true; break; } } if (foundIt) { System.out.println("Found " + searchfor + " at index " + i); } else { System.out.println(searchfor + " not in the array"); } }}
這個程式在數組終尋找數字12。break語句,如上的粗體,當找到只時,結束for迴圈。控制流程就跳轉到for迴圈後面的語句。程式輸出是:
Found 12 at index 4
無標籤break語句結束最裡面的switch,for,while,do-while語句。而標籤break結束最外面的語句。接下來的程式,BreakWithLabelDemo,類似前面的程式,但使用嵌套迴圈在二維數組裡尋找一個值。但值找到後,標籤break語句結束最外面的for迴圈(標籤為”search”):
class BreakWithLabelDemo { public static void main(String[] args) { int[][] arrayOfInts = { { 32, 87, 3, 589 }, { 12, 1076, 2000, 8 }, { 622, 127, 77, 955 } }; int searchfor = 12; int i; int j = 0; boolean foundIt = false; search: for (i = 0; i < arrayOfInts.length; i++) { for (j = 0; j < arrayOfInts[i].length; j++) { if (arrayOfInts[i][j] == searchfor) { foundIt = true; break search; } } } if (foundIt) { System.out.println("Found " + searchfor + " at " + i + ", " + j); } else { System.out.println(searchfor + " not in the array"); } }}
程式輸出是:
Found 12 at 1, 0
break語句結束標籤語句,它不是傳送控制流程到標籤處。控制流程傳送到緊隨標記(終止)聲明。 continue語句
continue語句忽略for,while,do-while的當前迭代。非標籤模式,忽略最裡面的迴圈體,然後計算迴圈控制的boolean運算式。接下來的程式,ContinueDemo,通過一個字串的步驟,計算字母“p”出現的次數。如果當前字元不是p,continue語句跳過迴圈的其他代碼,然後處理下一個字元。如果當前字元是p,程式自增字元數。
class ContinueDemo { public static void main(String[] args) { String searchMe = "peter piper picked a " + "peck of pickled peppers"; int max = searchMe.length(); int numPs = 0; for (int i = 0; i < max; i++) { // interested only in p's if (searchMe.charAt(i) != 'p') continue; // process p's numPs++; } System.out.println("Found " + numPs + " p's in the string."); }}
這裡是程式輸出:Found 9 p’s in the string.
為了更清晰看效果,嘗試去掉continue語句,重新編譯。再跑程式,count將是錯誤的,輸出是35,而不是9.
標籤continue語句忽略標籤標記的外層迴圈的當前迭代。下面的程式例子,ContinueWithLabelDemo,使用嵌套迴圈在字元傳的字串中搜尋字串。需要兩個嵌套迴圈:一個迭代字串,一個迭代正在被搜尋的字串。下面的程式ContinueWithLabelDemo,使用continue的標籤形式,忽略最外層的迴圈。
class ContinueWithLabelDemo { public static void main(String[] args) { String searchMe = "Look for a substring in me"; String substring = "sub"; boolean foundIt = false; int max = searchMe.length() - substring.length(); test: for (int i = 0; i <= max; i++) { int n = substring.length(); int j = i; int k = 0; while (n-- != 0) { if (searchMe.charAt(j++) != substring.charAt(k++)) { continue test; } } foundIt = true; break test; } System.out.println(foundIt ? "Found it" : "Didn't find it"); }}
這裡是程式輸出:Found it return語句
最後的分支語句是return語句。return語句從當前方法退出,控制流程返回到方法調用處。
return語句有兩種形式:一個是傳回值,一個是不傳回值。
為了返回一個值,簡單在return關鍵字後面把值放進去(或者放一個運算式計算)
return ++count;
return的值的資料類型,必須和方法聲明的傳回值的類型符合。
當方法聲明為void,使用下面形式的return不需要傳回值。
return; 腳註
轉載請註明出處,該部落格同步更新在我的個人部落格網站。1. 我的部落格網站:www.klsstt.com.