java編程思想總結是1個延續更新的系列,是本人對自己多年工作中使用到java的1個經驗性總結,也是溫故而知新吧,由于很多基礎的東西過了這么多年,平時工作中用不到也會遺忘掉,所以看看書,上上網,查查資料,也算是記錄下自己的筆記吧,過1段時間以后再來看看也是蠻不錯的,也希望能幫助到正在學習的人們,本系列將要總結1下幾點:
結合上1節,我們也從最基本的類開始,首先是經典的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則是這個類的名稱,1般類的命名都是首字母大寫的駝峰命名法。package是包的聲明,表明當前類的包路徑,static關鍵字代表該方法是靜態方法,main則是方法名稱,main方法是java程序默許生成的可履行的方法。
Java 是1種大小寫敏感的語言,這就意味著 Hello 和 hello 在 Java 中代表不同的意思。
Java 關鍵字總是小寫的
避免使用只有大小寫不同的變量名。
所有類的名稱首字母必須大寫。
始終確保在您的代碼和Java文件名相匹配的類名。
如果類名稱中包括幾個單詞,那末每一個單詞的首字母都要大寫。
例如類 HelloWord
標識符就是用于給 Java 程序中變量、類、方法等命名的符號。
使用標識符時,需要遵照幾條規則:
標識符可以由字母、數字、下劃線(_)、美元符($)組成,但不能包括 @、%、空格等其它特殊字符,不能以數字開頭。如:123name
標識符不能是 Java 關鍵字和保存字( Java 預留的關鍵字,以后的升級版本中有可能作為關鍵字),但可以包括關鍵字和保存字。如:不可使用 void 作為標識符,但是 Myvoid 可以。
- 標識符是嚴格辨別大小寫的。 1定要分清楚Hello 和 hello 是兩個不同的標識符哦!
- 標識符的命名最好能反應出其作用,做到見名知意。
訪問修飾符:default, public , protected, private
非訪問修飾符:final, abstract, strictfp
訪問控制:
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 拋出1個異常對象
throws 聲明1個異常可能被拋出
assert 斷言包相干:
import 引入
package 包基本類型:
boolean 布爾型
byte 字節型
char 字符型
double 雙精度,
float 浮點
int 整型
long 長整型
short 短整型
null 空
true 真
false 假
enum 枚舉變量援用:
super 父類,超類
this 本類
void 無返回值關鍵字(51)+保存字(const,goto)共53個
在程序中存在大量的數據來代表程序的狀態,其中有些數據在程序的運行進程中值會產生改變,有些數據在程序運行進程中值不能產生改變,這些數據在程序中分別被叫做變量和常量。
在實際的程序中,可以根據數據在程序運行中是不是產生改變,來選擇應當是使用變量代表還是常量代表。變量
變量代表程序的狀態。程序通過改變變量的值來改變全部程序的狀態,或說得更大1些,也就是實現程序的功能邏輯。
為了方便的援用變量的值,在程序中需要為變量設定1個名稱,這就是變量名。
例如在2D游戲程序中,需要代表人物的位置,則需要2個變量,1個是x坐標,1個是y坐標,在程序運行進程中,這兩個變量的值會產生改變。由于Java語言是1種強類型的語言,所以變量在使用之前必須首先聲明,在程序中聲明變量的語法格式以下:
數據類型 變量名稱;
例如:int x;
在該語法格式中,數據類型可以是Java語言中任意的類型,包括前面介紹到的基本數據類型和后續將要介紹的復合數據類型。變量名稱是該變量的標識符,需要符合標識符的命名規則,在實際使用中,該名稱1般和變量的用處對應,這樣便于程序的瀏覽。數據類型和變量名稱之間使用空格進行間隔,空格的個數不限,但是最少需要1個。語句使用“;”作為結束。
也能夠在聲明變量的同時,設定該變量的值,語法格式以下:
數據類型 變量名稱 = 值;
例如:int x = 10;
在該語法格式中,前面的語法和上面介紹的內容1致,后續的“=”代表賦值,其中的“值”代表具體的數據,注意區分“==”代表為判斷是不是相等。在該語法格式中,要求值的類型需要和聲明變量的數據類型1致。
在程序中,變量的值代表程序的狀態,在程序中可以通過變量名稱來援用變量中存儲的值,也能夠為變量重新賦值。例如:
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語法中,常量也能夠首先聲明,然后再進行賦值,但是只能賦值1次,示例代碼以下:
final int UP;
UP = 1;
final 用于聲明屬性(常量),方法和類,分別表示屬性1旦被分配內存空間就必須初始化(不會有默許初始化,局部變量也是如此,默許初始化只有普通的非final成員屬性,對static(無final修飾)類變量,類連接時候有默許初始化,對像private int a;在類實例化時,構造函數默許初始為0,總之,變量必須初始化后方可用,這是java的安全之1。
final這個關鍵字的含義是“這是沒法改變的”或“終態的”。
那末為何要禁止改變呢?
java語言的發明者可能由于兩個目的而禁止改變:
1. 效力問題:
jdk中的某些類的某些方法,是不允許被用戶覆蓋的,設計者可能認為,所用方法已是最好的方法,用戶私自覆蓋,或是由于忽視而覆蓋,就會影響JVM或是系統的系能;
2. 設計所需:
盡人皆知,有些情況必須使用final關鍵字,比如方法中的匿名內部類的參數傳遞
【修飾變量】:
final成員變量表示常量,只能被賦值1次,賦值后值不再改變。
【修飾方法】:
final方法不能被子類方法覆蓋,但可以被繼承。
【修飾類】:
final類不能被繼承,沒有子類,final類中所有方法都是final的。(如String類)被final修飾而沒有被static修飾的類的屬性變量只能在兩種情況下初始化(必須初始化):
a.在它被聲明的時候賦值
b.在構造函數里初始化
解釋: 當這個屬性被修飾為final,而非static的時候,它屬于類的實例對象的資源(實例常量),當類被加載進內存的時候這個屬性并沒有給其分配內存空間,而只是 定義了1個變量a,只有當類被實例化的時候這個屬性才被分配內存空間,而實例化的時候同時履行了構造函數,所以屬性被初始化了,也就符合了當它被分配內存 空間的時候就需要初始化,以后不再改變的條件.被static修飾而沒有被final修飾的類的屬性變量只能在兩種情況下初始化(可以不初始化):
a.在它被聲明的時候賦值
b.在靜態或非靜態快里初始化
解釋:
當類的屬性被同時被修飾為static時候,他屬于類的資源(類變量),在類加載后,進行連接時候,分3步: 先驗證;然后準備,準備時,先分配內存,接著默許初始化;可以進行解析。最后,進行類初始化,類初始化前,必須保證它的父類已初始化了,所以最早初始化的是超類,對接口,沒必要初始其父接口。類初始化時,它把類變量初始化語句及靜態初始化語句放到類初始化方法中,所以,如果無此兩種語句,也就沒類初始化方法,而構造函數是在當類 被實例化的時候才會履行,所以用構造函數,這時候候這個屬性沒有被初始化.程序就會報錯.而static塊是類被加載的時候履行,且只履行這1次,所以在 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塊是類被加載的時候履行,且只履行這1次,所以在 static塊中可以被初始化.java中的 final變量==常量
【final變量的變與不變】:final表示變量的值或援用不變
有人說final變量在賦值后就不可變,此變量可以是基本數據類型+String或是對象
那末這個不變到底指的是甚么呢?
這個不變指的是援用,是地址,而所援用的對象的內容依然是可變的。
注:如果為對象,注意此時類初始化條件
就是說,這個final變量永久指向某個對象,是1個常量指針,而不是指向常量的指針。
【final關鍵字的具體利用】:
【final+變量】:
在實際利用中,這類情勢是非常少見的。
比如logger是可以的,但是貌似其實不是非常實用,也許用戶依然希望通過setter來改變logger變量。
【static+final+變量】:
常量,常常使用。
【final+方法】:
JDK中經常使用,但是自己并未經常使用。
【final+類】:
helper類常常使用。
【final用于匿名內部類的參數傳遞】:
在多線程測試時,常常使用。
【final用于方法的參數】:
其實不經常使用。
數組時貯存有多重相同變量類型的對象。但是,數字本身也是堆中的1個對象。我們將要學習如何聲明,建立,初始化數組。
定義數組
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};的第2個方括號中不能加上數組長度,由于元素個數是由后面花括號的內容決定的。數組應用基礎
數組長度
Java中的每一個數組都有1個名為length的屬性,表示數組的長度。
length屬性是public final int的,即length是只讀的。數組長度1旦肯定,就不能改變大小。
2維數組
2維數組是數組的數組。
基本的定義方式有兩種情勢,如:
type[][] i = new type[2][3];(推薦)
type i[][] = new type[2][3];
變長的2維數組
2維數組的每一個元素都是1個1維數組,這些數組不1定都是等長的。
聲明2維數組的時候可以只指定第1維大小,空缺出第2維大小,以后再指定不同長度的數組。但是注意,第1維大小不能空缺(不能只指定列數不指定行數)。
2維數組也能夠在定義的時候初始化,使用花括號的嵌套完成,這時候候不指定兩個維數的大小,并且根據初始化值的個數不同,可以生成不同長度的數組元素。
集合類說明及區分
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection是最基本的集合接口,1個Collection代表1組Object,即Collection的元素(Elements)。1些 Collection允許相同的元素而另外一些不行,1些能排序而另外一些不行。
Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子接口”如List和Set。所有實現Collection接口的類都必須提供兩個標準的構造函數:無參數的構造函數用于創建1個空的Collection,有1個 Collection參數的構造函數用于創建1個新的Collection,這個新的Collection與傳入的Collection有相同的元素。后 1個構造函數允許用戶復制1個Collection。
如何遍歷Collection中的每個元素?不論Collection的實際類型如何,它都支持1個iterator()的方法,該方法返回1個迭代子,使用該迭代子便可逐1訪問Collection中每個元素。典型的用法以下:
Iterator it = collection.iterator(); // 取得1個迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下1個元素
}
由Collection接口派生的兩個接口是List和Set。
List是有序的Collection,使用此接口能夠精確的控制每一個元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似于數組下標)來訪問List中的元素,這類似于Java的數組。
和下面要提到的Set不同,List允許有相同的元素。除具有Collection接口必備的iterator()方法外,List還提供1個listIterator()方法,返回1個 ListIterator接口,和標準的Iterator接口相比,ListIterator多了1些add()之類的方法,允許添加,刪除,設定元素, 還能向前或向后遍歷。
實現List接口的經常使用類有LinkedList,ArrayList,Vector和Stack。
LinkedList實現了List接口,允許null元素。另外LinkedList提供額外的get,remove,insert方法在 LinkedList的首部或尾部。
這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque)。
注意LinkedList沒有同步方法。如果多個線程同時訪問1個List,則必須自己實現訪問同步。1種解決方法>是在創建List時構造1個同步的List:
List list = Collections.synchronizedList(new LinkedList(…));
ArrayList實現了可變大小的數組。它允許所有元素,包括null。ArrayList沒有同步。
size,isEmpty,get,set方法運行時間為常數。但是add方法開消為分攤的常數,
添加n個元素需要O(n)的時間。其他的方法運行時間為線性。
每一個ArrayList實例都有1個容量(Capacity),即用于存儲元素的數組的大小。這個容量可隨著不斷>添加新元素而自動增加,但是增長算法 并沒有定義。當需要插入大量元素時,在插入前可以調用>ensureCapacity方法來增加ArrayList的容量以提高插入效力。
和LinkedList1樣,ArrayList也是非同步的(unsynchronized)。
Vector非常類似ArrayList,但是Vector是同步的。由Vector創建的Iterator,雖然和 ArrayList創建的Iterator是同1接口,但是,由于Vector是同步的,當1個Iterator被創建而且正在被使用,另外一個線程改變了 Vector的狀態(例如,添加或刪除1些元素),這時候調用Iterator的方法時將拋出 ConcurrentModificationException,因此必須捕獲該異常。
- Stack 類
Stack繼承自Vector,實現1個落后先出的堆棧。Stack提供5個額外的方法使得Vector得以被當作堆棧使用。基本的push和pop 方法,還有peek方法得到棧頂的元素,empty方法測試堆棧是不是為空,search方法檢測1個元素在堆棧中的位置。Stack剛創建后是空棧。
Set是1種不包括重復的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有1個null元素。
很明顯,Set的構造函數有1個束縛條件,傳入的Collection參數不能包括重復的元素。
請注意:必須謹慎操作可變對象(Mutable Object)。如果1個Set中的可變元素改變了本身狀態致使Object.equals(Object)=true將致使1些問題。
- Map接口請注意,Map沒有繼承Collection接口,Map提供key到value的映照。1個Map中不能包括相同的key,每一個key只能映照1個 value。Map接口提供3種集合的視圖,Map的內容可以被當作1組key集合,1組value集合,或1組key-value映照。
Hashtable繼承Map接口,實現1個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));
要取出1個數,比如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不1定不同,如 果兩個不同對象的hashCode相同,這類現象稱為沖突,沖突會致使操作哈希表的時間開消增大,所以盡可能定義好的hashCode()方法,能加快哈希 表的操作。
如果相同的對象有不同的hashCode,對哈希表的操作會出現意想不到的結果(期待的get方法返回null),要避免這類問題,只需要牢記1條:要同時復寫equals方法和hashCode方法,而不要只寫其中1個。
Hashtable是同步的。
HashMap和Hashtable類似,不同的地方在于HashMap是非同步的,并且允許null,即null value和null key。,但是將HashMap視為Collection時(values()方法可返回Collection),其迭代子操作時間開消和HashMap 的容量成比例。因此,如果迭代操作的性能相當重要的話,不要將HashMap的初始化容量設得太高,或load factor太低。
WeakHashMap是1種改進的HashMap,它對key實行“弱援用”,如果1個key不再被外部所援用,那末該key可以被GC回收。
總結
如果觸及到堆棧,隊列等操作,應當斟酌用List,對需要快速插入,刪除元素,應當使用LinkedList,如果需要快速隨機訪問元素,應當使用ArrayList。
如果程序在單線程環境中,或訪問僅僅在1個線程中進行,斟酌非同步的類,其效力較高,如果多個線程可能同時操作1個類,應當使用同步的類。
要特別注意對哈希表的操作,作為key的對象要正確復寫equals和hashCode方法。
盡可能返回接口而非實際的類型,如返回List而非ArrayList,這樣如果以后需要將ArrayList換成LinkedList時,客戶端代碼不用改變。這就是針對抽象編程。
同步性
Vector是同步的。這個類中的1些方法保證了Vector中的對象是線程安全的。而ArrayList則是異步的,因此ArrayList中的對象并 不是線程安全的。由于同步的要求會影響履行的效力,所以如果你不需要線程安全的集合那末使用ArrayList是1個很好的選擇,這樣可以免由于同步帶 來的沒必要要的性能開消。
數據增長
從內部實現機制來說ArrayList和Vector都是使用數組(Array)來控制集合中的對象。當你向這兩種類型中增加元素的時候,如果元素的數目 超越了內部數組目前的長度它們都需要擴大內部數組的長度,Vector缺省情況下自動增長原來1倍的數組長度,ArrayList是原來的50%,所以最 后你取得的這個集合所占的空間總是比你實際需要的要大。所以如果你要在集合中保存大量的數據那末使用Vector有1些優勢,由于你可以通過設置集合的初 始化大小來避免沒必要要的資源開消。
使用模式
在ArrayList和Vector中,從1個指定的位置(通過索引)查找數據或是在集合的末尾增加、移除1個元素所花費的時間是1樣的,這個時間我們用 O(1)表示。但是,如果在集合的其他位置增加或移除元素那末花費的時間會呈線形增長:O(n-i),其中n代表集合中元素的個數,i代表元素增加或移除 元素的索引位置。
為何會這樣呢?以為在進行上述操作的時候集合中第i和第i個元素以后的所有元素都要履行位移的操作。
這1切意味著甚么呢?
這意味著,你只是查找特定位置的元素或只在集合的末端增加、移除元素,那末使用Vector或ArrayList都可以。如果是其他操作,你最好選擇其他 的集合操作類。比如,LinkList集合類在增加或移除集合中任何位置的元素所花費的時間都是1樣的?O(1),但它在索引1個元素的使用缺比較慢 -O(i),其中i是索引的位置.使用ArrayList也很容易,由于你可以簡單的使用索引來代替創建iterator對象的操作。LinkList也 會為每一個插入的元素創建對象,所有你要明白它也會帶來額外的開消。
最后,在《Practical Java》1書中Peter Haggar建議使用1個簡單的數組(Array)來代替Vector或ArrayList。特別是對履行效力要求高的程序更應如此。由于使用數組 (Array)避免了同步、額外的方法調用和沒必要要的重新分配空間的操作。
枚舉是在 Java5.0 版本中被引進的。枚舉限制了變量要有1些預先定義的值。枚舉列表中的值稱為枚舉值。
應用枚舉值可以大大減少你的代碼中的漏洞。
舉例來講,如果我們想為1家鮮榨果汁店編個程序,就能夠將杯子的尺寸限制為小中和大。這樣就能夠確保人們不會定大中小尺寸以外
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 編譯器疏忽。
行注釋:
//開始塊注釋:
/*開始
* /結束javadoc注釋:生成javadoc時,這樣的注釋會被生成標準的javaapi注釋,該注釋可以跨多行
/**
*
*/
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,類似前面的程序,但使用嵌套循環在2維數組里尋覓1個值。但值找到后,標簽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語句疏忽for,while,do-while確當前迭代。非標簽模式,疏忽最里面的循環體,然后計算循環控制的boolean表達式。接下來的程序,ContinueDemo,通過1個字符串的步驟,計算字母“p”出現的次數。如果當前字符不是p,continue語句跳過循環的其他代碼,然后處理下1個字符。如果當前字符是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,使用嵌套循環在字符傳的字串中搜索字串。需要兩個嵌套循環:1個迭代字串,1個迭代正在被搜索的字串。下面的程序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語句有兩種情勢:1個是返回值,1個是不返回值。
為了返回1個值,簡單在return關鍵字后面把值放進去(或放1個表達式計算)
return ++count;
return的值的數據類型,必須和方法聲明的返回值的類型符合。
當方法聲明為void,使用下面情勢的return不需要返回值。
return;
轉載請注明出處,該博客同步更新在我的個人博客網站。1.