目錄php
Java簡介 14html
主要特性 14前端
發展歷史 17java
的Java開發工具 18git
window系統安裝java 19正則表達式
Linux,UNIX,Solaris,FreeBSD環境變量設置25算法
流行JAVA開發工具 25shell
使用 Eclipse 運行第一個 Java 程序 26express
C : > javac HelloWorld.java 27
C : > java HelloWorld Hello World 27
B = 0000 1101----------------- 65
A ^ B = 0011 0001~A= 1100 0011 65
a || b = true!(a && b) = true 67
Java 循環結構 - for, while 及 do...while 72
Java 分支結構 - if...else/switch 77
Math 的 floor,round 和 ceil 方法實例比較 87
Java StringBuffer 和 StringBuilder 類 97
replaceFirst 和 replaceAll 方法 132
appendReplacement 和 appendTail 方法 133
PatternSyntaxException 類的方法 133
TestPassByValue.java 文件代碼: 138
FinalizationDemo.java 文件代碼: 143
Java 流(Stream)、文件(File)和IO 143
fileStreamTest2.java 文件代碼: 150
InsufficientFundsException.java 文件代碼: 163
CheckingAccount.java 文件代碼: 163
Java是由Sun Microsystems公司於1995年5月推出的Java面向對象程序設計語言和Java平臺的總稱。由James Gosling和同事們共同研發,並於1995年正式推出。
的Java分爲三個體系:
· JavaSE(J2SE)(Java2平臺標準版,java平臺標準版)
· JavaEE(J2EE)(Java 2平臺,企業版,java平臺企業版)
· JavaME(J2ME)(Java 2 Platform Micro Edition,Java平臺微型版)。
2005年6月,JavaOne大會召開,SUN公司公開Java SE 6.此時,Java的各類版本已經改名以取消其中的數字「2」:改名爲Java EE,J2SE改名爲Java SE,改名爲J2ME Java ME。
· 的Java語言是簡單的:
的Java語言的語法與C ^語言和C ++語言很接近,使得大多數程序員很容易學習和使用。另外一方面,Java的丟棄了C ++中不多使用的,很難理解的,使人迷惑的那些特性,如操做符重載,多繼承,自動的強制類型轉換。特別地,Java的語言不使用指針,而是引用。並提供了自動的廢料收集,使得程序員沒必要爲內存管理而擔心。
·
· Java的語言是面向對象的:
的Java語言提供類,接口和繼承等面向對象的特性,爲了簡單起見,只支持類之間的單繼承,但支持接口之間的多繼承,並支持類與接口之間的實現機制(關鍵字爲實現)的.java語言全面支持動態綁定,而C ++語言只對虛函數使用動態綁定。總之,Java的語言是一個純的面向對象程序設計語言。
·
· 的Java語言是分佈式的:
Java語言支持Internet應用的開發,在基本的Java應用編程接口中有一個網絡應用編程接口(java net),它提供了用於網絡應用編程的類庫,包括URL,URLConnection,Socket,ServerSocket等.Java的RMI(遠程方法激活)機制也是開發分佈式應用的重要手段。
·
· 的Java語言是健壯的:
的Java的強類型機制,異常處理,垃圾的自動收集等是Java的程序健壯性的重要保證。對指針的丟棄是Java的的明智選擇的.java的安全檢查機制使得Java的更具健壯性。
·
· Java的語言是安全的:
Java的一般被用在網絡環境中,爲此,爪哇提供了一個安全機制以防惡意代碼的攻擊。除了Java的語言具備的許多安全特性之外,Java的對經過網絡下載的類具備一個安全防範機制(類的ClassLoader ),如分配不一樣的名字空間以防替代本地的同名類,字節代碼檢查,並提供安全管理機制(類的SecurityManager)讓爪哇應用設置安全哨兵。
·
· 的Java語言是體系結構中立的:
的Java程序(後綴爲java的的文件)在的Java平臺上被編譯爲體系結構中立的字節碼格式(後綴爲類的文件),而後能夠在實現這個的Java平臺的任何系統中運行。這種途徑適合於異構的網絡環境和軟件的分發。
·
· 的Java語言是可移植的:
這種可移植性來源於體系結構中立性,另外,Java的還嚴格規定了各個基本數據類型的長度的.java系統自己也具備很強的可移植性,Java的編譯器是用Java的實現的,爪哇的運行環境是用ANSI C實現的。
·
· 的Java語言是解釋型的:
如前所述,Java的程序在的Java平臺上被編譯爲字節碼格式,而後能夠在實現這個的Java平臺的任何系統中運行。在運行時,Java的平臺中的的Java解釋器對這些字節碼進行解釋執行,執行過程當中須要的類在聯接階段被載入到運行環境中。
·
· Java的是高性能的:
與那些解釋型的高級腳本語言相比,Java的的確是高性能的。事實上,Java的的運行速度隨着JIT(剛剛在時間)編譯器技術的發展愈來愈接近於C ++。
·
· Java的語言是多線程的:
在的Java語言中,線程是一種特殊的對象,它必須由線程類或其子(孫)類來建立一般有兩種方法來建立線程:其一,使用型構爲主題(Runnable接口)的構造子將一個實現了Runnable接口接口的對象包裝成一個線程,其二,從主題類派生出子類並重寫的運行方法,使用該子類建立的對象即爲線程。值得注意的是主題類已經實現了了Runnable接口,所以,任何一個線程均有它的運行方法,而運行的方法中包含了線程所要運行的代碼。線程的活動由一組方法來控制的.java語言支持多個線程的同時執行,並提供多線程之間的同步機制(關鍵字爲同步)。
·
· 的Java語言是動態的:
的Java語言的設計目標之一是適應於動態變化的環境的.java程序須要的類可以動態地被載入到運行環境,也能夠經過網絡來載入所須要的類。這也有利於軟件的升級。另外,爪哇中的類有一個運行時刻的表示,能進行運行時刻的類型檢查。
·
· 1995年年5月23日,Java的語言誕生
· 1996年1月,第一個JDK-JDK1.0誕生
· 1996年4月,10個最主要的操做系統供應商申明將在其產品中嵌入JAVA技術
· 1996年9月,約8.3萬個網頁應用了JAVA技術來製做
· 1997年2月18日,JDK1.1發佈
· 1997年4月2日,JavaOne的會議召開,參與者逾一萬人,創當時全球同類會議規模之紀錄
· 1997年年9月,JavaDeveloperConnection社區成員超過十萬
· 1998年2月,JDK1.1被下載超過200萬次
· 1998年12月8日,JAVA2企業平臺J2EE發佈
· 1999年年6月,SUN公司發佈的Java的三個版本:標準版(JavaSE的,之前是J2SE),企業版(JavaEE的之前是J2EE)和微型版(的JavaME,之前是J2ME)
· 2000年5月8日,JDK1.3發佈
· 2000年5月29日,JDK1.4發佈
· 2001年6月5日,諾基亞宣佈,到2003年將出售1億部支持的Java的手機
· 2001年9月24日,J2EE1.3發佈
· 2002年2月26日,J2SE1.4發佈,自此Java的的計算能力有了大幅提高
· 2004年9月30日18:00 PM,J2SE1.5發佈,成爲Java語言發展史上的又一里程碑。爲了表示該版本的重要性,J2SE1.5改名爲Java SE 5.0
· 2005年6月,JavaOne大會召開,SUN公司公開Java SE 6.此時,Java的各類版本已經改名,以取消其中的數字「2」:J2EE改名爲Java EE,J2SE改名爲Java SE,J2ME改名爲Java ME
· 2006年12月,SUN公司發佈JRE6.0
· 2009年04月20日,甲骨文74億美圓收購Sun公司的Java取得的版權。
· 2010年11月,因爲甲骨文對於爪哇社區的不友善,所以阿帕奇揚言將退出JCP [4]。
· 2011年7月28日,甲骨文發佈java7.0的正式版。
· 2014年3月18日,Oracle公司發表Java SE 8。
Java的語言儘可能保證系統內存在1G以上,其餘工具以下所示:
· Linux系統,Mac OS系統,Windows 95/98/2000 / XP,WIN 7/8系統。
· 記事本編輯器或者其餘編輯器。
· IDE:Eclipse
安裝好以上的工具後,咱們就能夠輸出Java的第一個程序「Hello World!」
公共類HelloWorld { 公共靜態無效的主要(字符串[ ] 參數){ 系統。出去。println (「 Hello World 」 ); } }
在本章節中咱們將爲你們介紹如何搭建Java開發環境。
首先咱們須要下載java開發工具包JDK,下載地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html,點擊以下下載按鈕:
在下載頁面中你須要選擇接受許可,並根據本身的系統選擇對應的版本,本文以 Window 64位系統爲例:
下載後JDK的安裝根據提示進行,還有安裝JDK的時候也會安裝JRE,一併安裝就能夠了。
安裝JDK,安裝過程當中能夠自定義安裝目錄等信息,例如咱們選擇安裝目錄爲 C:\Program Files (x86)\Java\jdk1.8.0_91。
1.安裝完成後,右擊"個人電腦",點擊"屬性",選擇"高級系統設置";
2.選擇"高級"選項卡,點擊"環境變量";
而後就會出現以下圖所示的畫面:
在"系統變量"中設置3項屬性,JAVA_HOME,PATH,CLASSPATH(大小寫無所謂),若已存在則點擊"編輯",不存在則點擊"新建"。
變量設置參數以下:
· 變量名:JAVA_HOME
· 變量值:C:\Program Files (x86)\Java\jdk1.8.0_91 // 要根據本身的實際路徑配置
· 變量名:CLASSPATH
· 變量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; //記得前面有個"."
·
變量名:Path
·
·
變量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
·
注意:在 Windows10 中,由於系統的限制,path 變量只能夠使用 JDK 的絕對路徑。%JAVA_HOME% 會沒法識別,致使配置失敗。以下所示:
C:\Program Files (x86)\Java\jdk1.8.0_91\bin;C:\Program Files (x86)\Java\jdk1.8.0_91\jre\bin;
這是 Java 的環境配置,配置完成後,你能夠啓動 Eclipse 來編寫代碼,它會自動完成java環境的配置。
注意:若是使用1.5以上版本的JDK,不用設置CLASSPATH環境變量,也能夠正常編譯和運行Java程序。
一、"開始"->"運行",鍵入"cmd";
二、鍵入命令: java -version、java、javac 幾個命令,出現如下信息,說明環境變量配置成功;
環境變量PATH應該設定爲指向Java二進制文件安裝的位置。若是設置遇到困難,請參考shell文檔。
例如,假設你使用bash做爲shell,你能夠把下面的內容添加到你的 .bashrc文件結尾: export PATH=/path/to/java:$PATH
正所謂工欲善其事必先利其器,咱們在開發java語言過程當中一樣須要依款不錯的開發工具,目前市場上的IDE不少,本文爲你們推薦如下下幾款java開發工具:
·
Eclipse(推薦):另外一個免費開源的java IDE,下載地址: http://www.eclipse.org/
·
選擇 Eclipse IDE for Java Developers:
·
· Notepad++ : Notepad++ 是在微軟視窗環境之下的一個免費的代碼編輯器,下載地址: http://notepad-plus-plus.org/
· Netbeans:開源免費的java IDE,下載地址: http://www.netbeans.org/index.html
視頻演示以下所示:
HelloWorld.java 文件代碼:
public class HelloWorld { public static void main(String []args) { System.out.println("Hello World"); } }
一個Java程序能夠認爲是一系列對象的集合,而這些對象經過調用彼此的方法來協同工做。下面簡要介紹下類、對象、方法和實例變量的概念。
· 對象:對象是類的一個實例,有狀態和行爲。例如,一條狗是一個對象,它的狀態有:顏色、名字、品種;行爲有:搖尾巴、叫、吃等。
· 類:類是一個模板,它描述一類對象的行爲和狀態。
· 方法:方法就是行爲,一個類能夠有不少方法。邏輯運算、數據修改以及全部動做都是在方法中完成的。
· 實例變量:每一個對象都有獨特的實例變量,對象的狀態由這些實例變量的值決定。
下面看一個簡單的Java程序,它將打印字符串 Hello World
public class HelloWorld { /* 第一個Java程序 * 它將打印字符串 Hello World */ public static void main(String []args) { System.out.println("Hello World"); // 打印 Hello World } }
下面將逐步介紹如何保存、編譯以及運行這個程序:
· 打開Notepad,把上面的代碼添加進去;
· 把文件名保存爲:HelloWorld.java;
· 打開cmd命令窗口,進入目標文件所在的位置,假設是C:\
· 在命令行窗口鍵入 javac HelloWorld.java 按下enter鍵編譯代碼。若是代碼沒有錯誤,cmd命令提示符會進入下一行。(假設環境變量都設置好了)。
· 再鍵入java HelloWorld 按下Enter鍵就能夠運行程序了
你將會在窗口看到 Hello World
C : > java HelloWorld Hello World
Gif 圖演示:
編寫Java程序時,應注意如下幾點:
· 大小寫敏感:Java是大小寫敏感的,這就意味着標識符Hello與hello是不一樣的。
· 類名:對於全部的類來講,類名的首字母應該大寫。若是類名由若干單詞組成,那麼每一個單詞的首字母應該大寫,例如 MyFirstJavaClass 。
· 方法名:全部的方法名都應該以小寫字母開頭。若是方法名含有若干單詞,則後面的每一個單詞首字母大寫。
· 源文件名:源文件名必須和類名相同。當保存文件的時候,你應該使用類名做爲文件名保存(切記Java是大小寫敏感的),文件名的後綴爲.java。(若是文件名和類名不相同則會致使編譯錯誤)。
· 主方法入口:全部的Java 程序由public static void main(String []args)方法開始執行。
Java全部的組成部分都須要名字。類名、變量名以及方法名都被稱爲標識符。
關於Java標識符,有如下幾點須要注意:
· 全部的標識符都應該以字母(A-Z或者a-z),美圓符($)、或者下劃線(_)開始
· 首字符以後能夠是字母(A-Z或者a-z),美圓符($)、下劃線(_)或數字的任何字符組合
· 關鍵字不能用做標識符
· 標識符是大小寫敏感的
· 合法標識符舉例:age、$salary、_value、__1_value
· 非法標識符舉例:123abc、-salary
像其餘語言同樣,Java能夠使用修飾符來修飾類中方法和屬性。主要有兩類修飾符:
· 訪問控制修飾符 : default, public , protected, private
· 非訪問控制修飾符 : final, abstract, strictfp
在後面的章節中咱們會深刻討論Java修飾符。
Java中主要有以下幾種類型的變量
· 局部變量
· 類變量(靜態變量)
· 成員變量(非靜態變量)
數組是儲存在堆上的對象,能夠保存多個同類型變量。在後面的章節中,咱們將會學到如何聲明、構造以及初始化一個數組。
Java 5.0引入了枚舉,枚舉限制變量只能是預先設定好的值。使用枚舉能夠減小代碼中的bug。
例如,咱們爲果汁店設計一個程序,它將限制果汁爲小杯、中杯、大杯。這就意味着它不容許顧客點除了這三種尺寸外的果汁。
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 ; } }
注意:枚舉能夠單獨聲明或者聲明在類裏面。方法、變量、構造函數也能夠在枚舉中定義。
下面列出了Java保留字。這些保留字不能用於常量、變量、和任何標識符的名稱。
類別 |
關鍵字 |
說明 |
訪問控制 |
private |
私有的 |
protected |
受保護的 |
|
public |
公共的 |
|
類、方法和變量修飾符 |
abstract |
聲明抽象 |
class |
類 |
|
extends |
擴允,繼承 |
|
final |
最終值,不可改變的 |
|
implements |
實現(接口) |
|
interface |
接口 |
|
native |
本地,原生方法(非Java實現) |
|
new |
新,建立 |
|
static |
靜態 |
|
strictfp |
嚴格,精準 |
|
synchronized |
線程,同步 |
|
transient |
短暫 |
|
volatile |
易失 |
|
程序控制語句 |
break |
跳出循環 |
case |
定義一個值以供switch選擇 |
|
continue |
繼續 |
|
default |
默認 |
|
do |
運行 |
|
else |
不然 |
|
for |
循環 |
|
if |
若是 |
|
instanceof |
實例 |
|
return |
返回 |
|
switch |
根據值選擇執行 |
|
while |
循環 |
|
錯誤處理 |
assert |
斷言表達式是否爲真 |
catch |
捕捉異常 |
|
finally |
有沒有異常都執行 |
|
throw |
拋出一個異常對象 |
|
throws |
聲明一個異常可能被拋出 |
|
try |
捕獲異常 |
|
包相關 |
import |
引入 |
package |
包 |
|
基本類型 |
boolean |
布爾型 |
byte |
字節型 |
|
char |
字符型 |
|
double |
雙精度浮點 |
|
float |
單精度浮點 |
|
int |
整型 |
|
long |
長整型 |
|
short |
短整型 |
|
null |
空 |
|
變量引用 |
super |
父類,超類 |
this |
本類 |
|
void |
無返回值 |
|
保留關鍵字 |
goto |
是關鍵字,但不能使用 |
const |
是關鍵字,但不能使用 |
相似於C/C++,Java也支持單行以及多行註釋。註釋中的字符將被Java編譯器忽略。
public class HelloWorld { /* 這是第一個Java程序 *它將打印Hello World * 這是一個多行註釋的示例 */ public static void main(String []args){ // 這是單行註釋的示例 /* 這個也是單行註釋的示例 */ System.out.println("Hello World"); } }
空白行,或者有註釋的行,Java編譯器都會忽略掉。
在Java中,一個類能夠由其餘類派生。若是你要建立一個類,並且已經存在一個類具備你所須要的屬性或方法,那麼你能夠將新建立的類繼承該類。
利用繼承的方法,能夠重用已存在類的方法和屬性,而不用重寫這些代碼。被繼承的類稱爲超類(super class),派生類稱爲子類(subclass)。
在Java中,接口可理解爲對象間相互通訊的協議。接口在繼承中扮演着很重要的角色。
接口只定義派生要用到的方法,可是方法的具體實現徹底取決於派生類。
以下圖所示:
Java做爲一種面嚮對象語言。支持如下基本概念:
· 多態
· 繼承
· 封裝
· 抽象
· 類
· 對象
· 實例
· 方法
· 重載
本節咱們重點研究對象和類的概念。
· 對象:對象是類的一個實例(對象不是找個女友),有狀態和行爲。例如,一條狗是一個對象,它的狀態有:顏色、名字、品種;行爲有:搖尾巴、叫、吃等。
· 類:類是一個模板,它描述一類對象的行爲和狀態。
下圖中男孩女孩爲類,而具體的每一個人爲該類的對象:
如今讓咱們深刻了解什麼是對象。看看周圍真實的世界,會發現身邊有不少對象,車,狗,人等等。全部這些對象都有本身的狀態和行爲。
拿一條狗來舉例,它的狀態有:名字、品種、顏色,行爲有:叫、搖尾巴和跑。
對比現實對象和軟件對象,它們之間十分類似。
軟件對象也有狀態和行爲。軟件對象的狀態就是屬性,行爲經過方法體現。
在軟件開發中,方法操做對象內部狀態的改變,對象的相互調用也是經過方法來完成。
類能夠當作是建立Java對象的模板。
經過下面一個簡單的類來理解下Java中類的定義:
public class Dog{ String breed; int age; String color; void barking(){ } void hungry(){ } void sleeping(){ } }
一個類能夠包含如下類型變量:
· 局部變量:在方法、構造方法或者語句塊中定義的變量被稱爲局部變量。變量聲明和初始化都是在方法中,方法結束後,變量就會自動銷燬。
· 成員變量:成員變量是定義在類中,方法體以外的變量。這種變量在建立對象的時候實例化。成員變量能夠被類中方法、構造方法和特定類的語句塊訪問。
· 類變量:類變量也聲明在類中,方法體以外,但必須聲明爲static類型。
一個類能夠擁有多個方法,在上面的例子中:barking()、hungry()和sleeping()都是Dog類的方法。
每一個類都有構造方法。若是沒有顯式地爲類定義構造方法,Java編譯器將會爲該類提供一個默認構造方法。
在建立一個對象的時候,至少要調用一個構造方法。構造方法的名稱必須與類同名,一個類能夠有多個構造方法。
下面是一個構造方法示例:
public class Puppy{ public Puppy(){ } public Puppy(String name){ // 這個構造器僅有一個參數:name } }
對象是根據類建立的。在Java中,使用關鍵字new來建立一個新的對象。建立對象須要如下三步:
· 聲明:聲明一個對象,包括對象名稱和對象類型。
· 實例化:使用關鍵字new來建立一個對象。
· 初始化:使用new建立對象時,會調用構造方法初始化對象。
下面是一個建立對象的例子:
public class Puppy{ public Puppy(String name){ //這個構造器僅有一個參數:name System.out.println("小狗的名字是 : " + name ); } public static void main(String []args){ // 下面的語句將建立一個Puppy對象 Puppy myPuppy = new Puppy( "tommy" ); } }
編譯並運行上面的程序,會打印出下面的結果:
小狗的名字是 : tommy
經過已建立的對象來訪問成員變量和成員方法,以下所示:
/* 實例化對象 */ ObjectReference = new Constructor(); /* 訪問類中的變量 */ ObjectReference.variableName; /* 訪問類中的方法 */ ObjectReference.MethodName();
下面的例子展現如何訪問實例變量和調用成員方法:
public class Puppy{ int puppyAge; public Puppy(String name){ // 這個構造器僅有一個參數:name System.out.println("小狗的名字是 : " + name ); } public void setAge( int age ){ puppyAge = age; } public int getAge( ){ System.out.println("小狗的年齡爲 : " + puppyAge ); return puppyAge; } public static void main(String []args){ /* 建立對象 */ Puppy myPuppy = new Puppy( "tommy" ); /* 經過方法來設定age */ myPuppy.setAge( 2 ); /* 調用另外一個方法獲取age */ myPuppy.getAge( ); /*你也能夠像下面這樣訪問成員變量 */ System.out.println("變量值 : " + myPuppy.puppyAge ); } }
編譯並運行上面的程序,產生以下結果:
小狗的名字是 : tommy小狗的年齡爲 : 2變量值 : 2
在本節的最後部分,咱們將學習源文件的聲明規則。當在一個源文件中定義多個類,而且還有import語句和package語句時,要特別注意這些規則。
· 一個源文件中只能有一個public類
· 一個源文件能夠有多個非public類
· 源文件的名稱應該和public類的類名保持一致。例如:源文件中public類的類名是Employee,那麼源文件應該命名爲Employee.java。
· 若是一個類定義在某個包中,那麼package語句應該在源文件的首行。
· 若是源文件包含import語句,那麼應該放在package語句和類定義之間。若是沒有package語句,那麼import語句應該在源文件中最前面。
· import語句和package語句對源文件中定義的全部類都有效。在同一源文件中,不能給不一樣的類不一樣的包聲明。
類有若干種訪問級別,而且類也分不一樣的類型:抽象類和final類等。這些將在訪問控制章節介紹。
除了上面提到的幾種類型,Java還有一些特殊的類,如:內部類、匿名類。
包主要用來對類和接口進行分類。當開發Java程序時,可能編寫成百上千的類,所以頗有必要對類和接口進行分類。
在Java中,若是給出一個完整的限定名,包括包名、類名,那麼Java編譯器就能夠很容易地定位到源代碼或者類。Import語句就是用來提供一個合理的路徑,使得編譯器能夠找到某個類。
例如,下面的命令行將會命令編譯器載入java_installation/java/io路徑下的全部類
import java.io.*;
在該例子中,咱們建立兩個類:Employee 和 EmployeeTest。
首先打開文本編輯器,把下面的代碼粘貼進去。注意將文件保存爲 Employee.java。
Employee類有四個成員變量:name、age、designation和salary。該類顯式聲明瞭一個構造方法,該方法只有一個參數。
import java.io.*; public class Employee{ String name; int age; String designation; double salary; // Employee 類的構造器 public Employee(String name){ this.name = name; } // 設置age的值 public void empAge(int empAge){ age = empAge; } /* 設置designation的值*/ public void empDesignation(String empDesig){ designation = empDesig; } /* 設置salary的值*/ public void empSalary(double empSalary){ salary = empSalary; } /* 打印信息 */ public void printEmployee(){ System.out.println("名字:"+ name ); System.out.println("年齡:" + age ); System.out.println("職位:" + designation ); System.out.println("薪水:" + salary); } }
程序都是從main方法開始執行。爲了能運行這個程序,必須包含main方法而且建立一個實例對象。
下面給出EmployeeTest類,該類實例化2個 Employee 類的實例,並調用方法設置變量的值。
將下面的代碼保存在 EmployeeTest.java文件中。
import java.io.*; public class EmployeeTest{ public static void main(String args[]){ /* 使用構造器建立兩個對象 */ Employee empOne = new Employee("RUNOOB1"); Employee empTwo = new Employee("RUNOOB2"); // 調用這兩個對象的成員方法 empOne.empAge(26); empOne.empDesignation("高級程序員"); empOne.empSalary(1000); empOne.printEmployee(); empTwo.empAge(21); empTwo.empDesignation("菜鳥程序員"); empTwo.empSalary(500); empTwo.printEmployee(); } }
編譯這兩個文件而且運行 EmployeeTest 類,能夠看到以下結果:
$ javac EmployeeTest.java
$ java EmployeeTest 名字:RUNOOB1年齡:26職位:高級程序員薪水:1000.0名字:RUNOOB2年齡:21職位:菜鳥程序員薪水:500.0
變量就是申請內存來存儲值。也就是說,當建立變量的時候,須要在內存中申請空間。
內存管理系統根據變量的類型爲變量分配存儲空間,分配的空間只能用來儲存該類型數據。
所以,經過定義不一樣類型的變量,能夠在內存中儲存整數、小數或者字符。
Java 的兩大數據類型:
· 內置數據類型
· 引用數據類型
Java語言提供了八種基本類型。六種數字類型(四個整數型,兩個浮點型),一種字符類型,還有一種布爾型。
byte:
· byte 數據類型是8位、有符號的,以二進制補碼錶示的整數;
· 最小值是 -128(-2^7);
· 最大值是 127(2^7-1);
· 默認值是 0;
· byte 類型用在大型數組中節約空間,主要代替整數,由於 byte 變量佔用的空間只有 int 類型的四分之一;
· 例子:byte a = 100,byte b = -50。
short:
· short 數據類型是 16 位、有符號的以二進制補碼錶示的整數
· 最小值是 -32768(-2^15);
· 最大值是 32767(2^15 - 1);
· Short 數據類型也能夠像 byte 那樣節省空間。一個short變量是int型變量所佔空間的二分之一;
· 默認值是 0;
· 例子:short s = 1000,short r = -20000。
int:
· int 數據類型是32位、有符號的以二進制補碼錶示的整數;
· 最小值是 -2,147,483,648(-2^31);
· 最大值是 2,147,483,647(2^31 - 1);
· 通常地整型變量默認爲 int 類型;
· 默認值是 0 ;
· 例子:int a = 100000, int b = -200000。
long:
· long 數據類型是 64 位、有符號的以二進制補碼錶示的整數;
· 最小值是 -9,223,372,036,854,775,808(-2^63);
· 最大值是 9,223,372,036,854,775,807(2^63 -1);
· 這種類型主要使用在須要比較大整數的系統上;
· 默認值是 0L;
· 例子: long a = 100000L,Long b = -200000L。
"L"理論上不分大小寫,可是若寫成"l"容易與數字"1"混淆,不容易分辯。因此最好大寫。
float:
· float 數據類型是單精度、32位、符合IEEE 754標準的浮點數;
· float 在儲存大型浮點數組的時候可節省內存空間;
· 默認值是 0.0f;
· 浮點數不能用來表示精確的值,如貨幣;
· 例子:float f1 = 234.5f。
double:
· double 數據類型是雙精度、64 位、符合IEEE 754標準的浮點數;
· 浮點數的默認類型爲double類型;
· double類型一樣不能表示精確的值,如貨幣;
· 默認值是 0.0d;
· 例子:double d1 = 123.4。
boolean:
· boolean數據類型表示一位的信息;
· 只有兩個取值:true 和 false;
· 這種類型只做爲一種標誌來記錄 true/false 狀況;
· 默認值是 false;
· 例子:boolean one = true。
char:
· char類型是一個單一的 16 位 Unicode 字符;
· 最小值是 \u0000(即爲0);
· 最大值是 \uffff(即爲65,535);
· char 數據類型能夠儲存任何字符;
· 例子:char letter = 'A';。
對於數值類型的基本類型的取值範圍,咱們無需強制去記憶,由於它們的值都已經以常量的形式定義在對應的包裝類中了。請看下面的例子:
public class PrimitiveTypeTest { public static void main(String[] args) { // byte System.out.println("基本類型:byte 二進制位數:" + Byte.SIZE); System.out.println("包裝類:java.lang.Byte"); System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE); System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE); System.out.println(); // short System.out.println("基本類型:short 二進制位數:" + Short.SIZE); System.out.println("包裝類:java.lang.Short"); System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE); System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE); System.out.println(); // int System.out.println("基本類型:int 二進制位數:" + Integer.SIZE); System.out.println("包裝類:java.lang.Integer"); System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE); System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE); System.out.println(); // long System.out.println("基本類型:long 二進制位數:" + Long.SIZE); System.out.println("包裝類:java.lang.Long"); System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE); System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE); System.out.println(); // float System.out.println("基本類型:float 二進制位數:" + Float.SIZE); System.out.println("包裝類:java.lang.Float"); System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE); System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE); System.out.println(); // double System.out.println("基本類型:double 二進制位數:" + Double.SIZE); System.out.println("包裝類:java.lang.Double"); System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE); System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE); System.out.println(); // char System.out.println("基本類型:char 二進制位數:" + Character.SIZE); System.out.println("包裝類:java.lang.Character"); // 以數值形式而不是字符形式將Character.MIN_VALUE輸出到控制檯 System.out.println("最小值:Character.MIN_VALUE=" + (int) Character.MIN_VALUE); // 以數值形式而不是字符形式將Character.MAX_VALUE輸出到控制檯 System.out.println("最大值:Character.MAX_VALUE=" + (int) Character.MAX_VALUE); } }
編譯以上代碼輸出結果以下所示:
基本類型:byte 二進制位數:8包裝類:java.lang.Byte最小值:Byte.MIN_VALUE=-128最大值:Byte.MAX_VALUE=127
基本類型:short 二進制位數:16包裝類:java.lang.Short最小值:Short.MIN_VALUE=-32768最大值:Short.MAX_VALUE=32767
基本類型:int 二進制位數:32包裝類:java.lang.Integer最小值:Integer.MIN_VALUE=-2147483648最大值:Integer.MAX_VALUE=2147483647
基本類型:long 二進制位數:64包裝類:java.lang.Long最小值:Long.MIN_VALUE=-9223372036854775808最大值:Long.MAX_VALUE=9223372036854775807
基本類型:float 二進制位數:32包裝類:java.lang.Float最小值:Float.MIN_VALUE=1.4E-45最大值:Float.MAX_VALUE=3.4028235E38
基本類型:double 二進制位數:64包裝類:java.lang.Double最小值:Double.MIN_VALUE=4.9E-324最大值:Double.MAX_VALUE=1.7976931348623157E308
基本類型:char 二進制位數:16包裝類:java.lang.Character最小值:Character.MIN_VALUE=0最大值:Character.MAX_VALUE=65535
Float和Double的最小值和最大值都是以科學記數法的形式輸出的,結尾的"E+數字"表示E以前的數字要乘以10的多少次方。好比3.14E3就是3.14 × 103 =3140,3.14E-3 就是 3.14 x 10-3 =0.00314。
實際上,JAVA中還存在另一種基本類型void,它也有對應的包裝類 java.lang.Void,不過咱們沒法直接對它們進行操做。
· 在Java中,引用類型的變量很是相似於C/C++的指針。引用類型指向一個對象,指向對象的變量是引用變量。這些變量在聲明時被指定爲一個特定的類型,好比 Employee、Puppy 等。變量一旦聲明後,類型就不能被改變了。
· 對象、數組都是引用數據類型。
· 全部引用類型的默認值都是null。
· 一個引用變量能夠用來引用任何與之兼容的類型。
· 例子:Site site = new Site("Runoob")。
常量在程序運行時是不能被修改的。
在 Java 中使用 final 關鍵字來修飾常量,聲明方式和變量相似:
final double PI = 3.1415927;
雖然常量名也能夠用小寫,但爲了便於識別,一般使用大寫字母表示常量。
字面量能夠賦給任何內置類型的變量。例如:
byte a = 68;char a = 'A'
byte、int、long、和short均可以用十進制、16進制以及8進制的方式來表示。
當使用常量的時候,前綴 0 表示 8 進制,而前綴 0x 表明 16 進制, 例如:
int decimal = 100;int octal = 0144;int hexa = 0x64;
和其餘語言同樣,Java的字符串常量也是包含在兩個引號之間的字符序列。下面是字符串型字面量的例子:
"Hello World""two\nlines""\"This is in quotes\""
字符串常量和字符常量均可以包含任何Unicode字符。例如:
char a = '\u0001';String a = "\u0001";
Java語言支持一些特殊的轉義字符序列。
符號 |
字符含義 |
\n |
換行 (0x0a) |
\r |
回車 (0x0d) |
\f |
換頁符(0x0c) |
\b |
退格 (0x08) |
\0 |
空字符 (0x20) |
\s |
字符串 |
\t |
製表符 |
\" |
雙引號 |
\' |
單引號 |
\\ |
反斜槓 |
\ddd |
八進制字符 (ddd) |
\uxxxx |
16進制Unicode字符 (xxxx) |
整型、實型(常量)、字符型數據能夠混合運算。運算中,不一樣類型的數據先轉化爲同一類型,而後進行運算。
轉換從低級到高級。
低 ------------------------------------> 高
byte,short,char—> int —> long—> float —> double
數據類型轉換必須知足以下規則:
·
1. 不能對boolean類型進行類型轉換。
·
·
2. 不能把對象類型轉換成不相關類的對象。
·
·
3. 在把容量大的類型轉換爲容量小的類型時必須使用強制類型轉換。
·
·
4. 轉換過程當中可能致使溢出或損失精度,例如:
·
int i =128; byte b = (byte)i;
·
由於 byte 類型是 8 位,最大值爲127,因此當 int 強制轉換爲 byte 類型時,值 128 時候就會致使溢出。
·
·
5. 浮點數到整數的轉換是經過捨棄小數獲得,而不是四捨五入,例如:
·
(int)23.7 == 23; (int)-45.89f == -45
·
必須知足轉換前的數據類型的位數要低於轉換後的數據類型,例如: short數據類型的位數爲16位,就能夠自動轉換位數爲32的int類型,一樣float數據類型的位數爲32,能夠自動轉換爲64位的double類型。
public class ZiDongLeiZhuan{ public static void main(String[] args){ char c1='a';//定義一個char類型 int i1 = c1;//char自動類型轉換爲int System.out.println("char自動類型轉換爲int後的值等於"+i1); char c2 = 'A';//定義一個char類型 int i2 = c2+1;//char 類型和 int 類型計算 System.out.println("char類型和int計算後的值等於"+i2); } }
運行結果爲:
char自動類型轉換爲int後的值等於97char類型和int計算後的值等於66
解析:c1的值爲字符'a',查ascii碼錶可知對應的int類型值爲97,'A'對應值爲65,因此i2=65+1=66。
·
1. 條件是轉換的數據類型必須是兼容的。
·
·
2. 格式:(type)value type是要強制類型轉換後的數據類型 實例:
·
·
public class QiangZhiZhuanHuan{ public static void main(String[] args){ int i1 = 123; byte b = (byte)i1;//強制類型轉換爲byte System.out.println("int強制類型轉換爲byte後的值等於"+b); } }
·
運行結果:
·
int強制類型轉換爲byte後的值等於123
·
·
1. 整數的默認類型是 int。
·
·
2. 浮點型不存在這種狀況,由於在定義 float 類型時必須在數字後面跟上 F 或者 f。
·
在Java語言中,全部的變量在使用前必須聲明。聲明變量的基本格式以下:
type identifier [ = value][, identifier [= value] ...] ;
格式說明:type爲Java數據類型。identifier是變量名。能夠使用逗號隔開來聲明多個同類型變量。
如下列出了一些變量的聲明實例。注意有些包含了初始化過程。
int a, b, c; // 聲明三個int型整數:a、 b、c int d = 3, e = 4, f = 5; // 聲明三個整數並賦予初值 byte z = 22; // 聲明並初始化 z String s = "runoob"; // 聲明並初始化字符串 s double pi = 3.14159; // 聲明瞭雙精度浮點型變量 pi char x = 'x'; // 聲明變量 x 的值是字符 'x'。
Java語言支持的變量類型有:
· 類變量:獨立於方法以外的變量,用 static 修飾。
· 實例變量:獨立於方法以外的變量,不過沒有 static 修飾。
· 局部變量:類的方法中的變量。
public class Variable{ static int allClicks=0; // 類變量 String str="hello world"; // 實例變量 public void method(){ int i =0; // 局部變量 } }
· 局部變量聲明在方法、構造方法或者語句塊中;
· 局部變量在方法、構造方法、或者語句塊被執行的時候建立,當它們執行完成後,變量將會被銷燬;
· 訪問修飾符不能用於局部變量;
· 局部變量只在聲明它的方法、構造方法或者語句塊中可見;
· 局部變量是在棧上分配的。
· 局部變量沒有默認值,因此局部變量被聲明後,必須通過初始化,才能夠使用。
在如下實例中age是一個局部變量。定義在pupAge()方法中,它的做用域就限制在這個方法中。
package com.runoob.test; public class Test{ public void pupAge(){ int age = 0; age = age + 7; System.out.println("小狗的年齡是: " + age); } public static void main(String args[]){ Test test = new Test(); test.pupAge(); } }
以上實例編譯運行結果以下:
小狗的年齡是: 7
在下面的例子中 age 變量沒有初始化,因此在編譯時會出錯:
package com.runoob.test; public class Test{ public void pupAge(){ int age; age = age + 7; System.out.println("小狗的年齡是 : " + age); } public static void main(String args[]){ Test test = new Test(); test.pupAge(); } }
以上實例編譯運行結果以下:
Test.java:4:variable number might not have been initialized
age = age + 7;
^1 error
· 實例變量聲明在一個類中,但在方法、構造方法和語句塊以外;
· 當一個對象被實例化以後,每一個實例變量的值就跟着肯定;
· 實例變量在對象建立的時候建立,在對象被銷燬的時候銷燬;
· 實例變量的值應該至少被一個方法、構造方法或者語句塊引用,使得外部可以經過這些方式獲取實例變量信息;
· 實例變量能夠聲明在使用前或者使用後;
· 訪問修飾符能夠修飾實例變量;
· 實例變量對於類中的方法、構造方法或者語句塊是可見的。通常狀況下應該把實例變量設爲私有。經過使用訪問修飾符能夠使實例變量對子類可見;
· 實例變量具備默認值。數值型變量的默認值是0,布爾型變量的默認值是false,引用類型變量的默認值是null。變量的值能夠在聲明時指定,也能夠在構造方法中指定;
· 實例變量能夠直接經過變量名訪問。但在靜態方法以及其餘類中,就應該使用徹底限定名:ObejectReference.VariableName。
import java.io.*; public class Employee{ // 這個實例變量對子類可見 public String name; // 私有變量,僅在該類可見 private double salary; //在構造器中對name賦值 public Employee (String empName){ name = empName; } //設定salary的值 public void setSalary(double empSal){ salary = empSal; } // 打印信息 public void printEmp(){ System.out.println("名字 : " + name ); System.out.println("薪水 : " + salary); } public static void main(String args[]){ Employee empOne = new Employee("RUNOOB"); empOne.setSalary(1000); empOne.printEmp(); } }
以上實例編譯運行結果以下:
$ javac Employee.java
$ java Employee名字 : RUNOOB薪水 : 1000.0
· 類變量也稱爲靜態變量,在類中以static關鍵字聲明,但必須在方法構造方法和語句塊以外。
· 不管一個類建立了多少個對象,類只擁有類變量的一份拷貝。
· 靜態變量除了被聲明爲常量外不多使用。常量是指聲明爲public/private,final和static類型的變量。常量初始化後不可改變。
· 靜態變量儲存在靜態存儲區。常常被聲明爲常量,不多單獨使用static聲明變量。
· 靜態變量在程序開始時建立,在程序結束時銷燬。
· 與實例變量具備類似的可見性。但爲了對類的使用者可見,大多數靜態變量聲明爲public類型。
· 默認值和實例變量類似。數值型變量默認值是0,布爾型默認值是false,引用類型默認值是null。變量的值能夠在聲明的時候指定,也能夠在構造方法中指定。此外,靜態變量還能夠在靜態語句塊中初始化。
· 靜態變量能夠經過:ClassName.VariableName的方式訪問。
· 類變量被聲明爲public static final類型時,類變量名稱通常建議使用大寫字母。若是靜態變量不是public和final類型,其命名方式與實例變量以及局部變量的命名方式一致。
實例:
import java.io.*; public class Employee { //salary是靜態的私有變量 private static double salary; // DEPARTMENT是一個常量 public static final String DEPARTMENT = "開發人員"; public static void main(String args[]){ salary = 10000; System.out.println(DEPARTMENT+"平均工資:"+salary); } }
以上實例編譯運行結果以下:
開發人員平均工資:10000.0
注意:若是其餘類想要訪問該變量,能夠這樣訪問:Employee.DEPARTMENT。
Java語言提供了不少修飾符,主要分爲如下兩類:
· 訪問修飾符
· 非訪問修飾符
修飾符用來定義類、方法或者變量,一般放在語句的最前端。咱們經過下面的例子來講明:
public class className { // ... } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { // 方法體 }
Java中,能夠使用訪問控制符來保護對類、變量、方法和構造方法的訪問。Java 支持 4 種不一樣的訪問權限。
·
default (即缺省,什麼也不寫): 在同一包內可見,不使用任何修飾符。使用對象:類、接口、變量、方法。
·
·
private : 在同一類內可見。使用對象:變量、方法。 注意:不能修飾類(外部類)
·
·
public : 對全部類可見。使用對象:類、接口、變量、方法
·
·
protected : 對同一包內的類和全部子類可見。使用對象:變量、方法。 注意:不能修飾類(外部類)。
·
咱們能夠能夠經過如下表來講明訪問權限:
訪問控制 |
|||||
修飾符 |
當前類 |
同一包內 |
子孫類 |
其餘包 |
其餘包子孫類 |
public |
Y |
Y |
Y |
Y |
Y |
protected |
Y |
Y |
Y |
N |
Y/N(說明) |
default |
Y |
Y |
N |
N |
N |
private |
Y |
N |
N |
N |
N |
使用默認訪問修飾符聲明的變量和方法,對同一個包內的類是可見的。接口裏的變量都隱式聲明爲 public static final,而接口裏的方法默認狀況下訪問權限爲 public。
以下例所示,變量和方法的聲明能夠不使用任何修飾符。
String version = "1.5.1"; boolean processOrder() { return true; }
私有訪問修飾符是最嚴格的訪問級別,因此被聲明爲 private 的方法、變量和構造方法只能被所屬類訪問,而且類和接口不能聲明爲 private。
聲明爲私有訪問類型的變量只能經過類中公共的 getter 方法被外部類訪問。
Private 訪問修飾符的使用主要用來隱藏類的實現細節和保護類的數據。
下面的類使用了私有訪問修飾符:
public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }
實例中,Logger 類中的 format 變量爲私有變量,因此其餘類不能直接獲得和設置該變量的值。爲了使其餘類可以操做該變量,定義了兩個 public 方法:getFormat() (返回 format的值)和 setFormat(String)(設置 format 的值)
被聲明爲 public 的類、方法、構造方法和接口可以被任何其餘類訪問。
若是幾個相互訪問的 public 類分佈在不一樣的包中,則須要導入相應 public 類所在的包。因爲類的繼承性,類全部的公有方法和變量都能被其子類繼承。
如下函數使用了公有訪問控制:
public static void main(String[] arguments) { // ... }
Java 程序的 main() 方法必須設置成公有的,不然,Java 解釋器將不能運行該類。
protected 須要從如下兩個點來分析說明:
·
子類與基類在同一包中:被聲明爲 protected 的變量、方法和構造器能被同一個包中的任何其餘類訪問;
·
·
子類與基類不在同一包中:那麼在子類中,子類實例能夠訪問其從基類繼承而來的 protected 方法,而不能訪問基類實例的protected方法。
·
protected 訪問修飾符不能修飾類和接口,方法和成員變量可以聲明爲 protected,可是接口的成員變量和成員方法不能聲明爲 protected。
子類能訪問 protected 修飾符聲明的方法和變量,這樣就能保護不相關的類使用這些方法和變量。
下面的父類使用了 protected 訪問修飾符,子類重寫了父類的 openSpeaker() 方法。
class AudioPlayer { protected boolean openSpeaker(Speaker sp) { // 實現細節 } } class StreamingAudioPlayer extends AudioPlayer { protected boolean openSpeaker(Speaker sp) { // 實現細節 } }
若是把 openSpeaker() 方法聲明爲 private,那麼除了 AudioPlayer 以外的類將不能訪問該方法。
若是把 openSpeaker() 聲明爲 public,那麼全部的類都可以訪問該方法。
若是咱們只想讓該方法對其所在類的子類可見,則將該方法聲明爲 protected。
protected 是最難理解的一種 Java 類成員訪問權限修飾詞,更多詳細內容請查看 Java protected 關鍵字詳解。
請注意如下方法繼承的規則:
·
父類中聲明爲 public 的方法在子類中也必須爲 public。
·
·
父類中聲明爲 protected 的方法在子類中要麼聲明爲 protected,要麼聲明爲 public,不能聲明爲 private。
·
·
父類中聲明爲 private 的方法,不可以被繼承。
·
爲了實現一些其餘的功能,Java 也提供了許多非訪問修飾符。
static 修飾符,用來修飾類方法和類變量。
final 修飾符,用來修飾類、方法和變量,final 修飾的類不可以被繼承,修飾的方法不能被繼承類從新定義,修飾的變量爲常量,是不可修改的。
abstract 修飾符,用來建立抽象類和抽象方法。
synchronized 和 volatile 修飾符,主要用於線程的編程。
·
靜態變量:
·
static 關鍵字用來聲明獨立於對象的靜態變量,不管一個類實例化多少對象,它的靜態變量只有一份拷貝。 靜態變量也被稱爲類變量。局部變量不能被聲明爲 static 變量。
·
·
靜態方法:
·
static 關鍵字用來聲明獨立於對象的靜態方法。靜態方法不能使用類的非靜態變量。靜態方法從參數列表獲得數據,而後計算這些數據。
·
對類變量和方法的訪問能夠直接使用 classname.variablename 和 classname.methodname 的方式訪問。
以下例所示,static修飾符用來建立類方法和類變量。
public class InstanceCounter { private static int numInstances = 0; protected static int getCount() { return numInstances; } private static void addInstance() { numInstances++; } InstanceCounter() { InstanceCounter.addInstance(); } public static void main(String[] arguments) { System.out.println("Starting with " + InstanceCounter.getCount() + " instances"); for (int i = 0; i < 500; ++i){ new InstanceCounter(); } System.out.println("Created " + InstanceCounter.getCount() + " instances"); } }
以上實例運行編輯結果以下:
Started with 0 instancesCreated 500 instances
final 變量:
final 變量能被顯式地初始化而且只能初始化一次。被聲明爲 final 的對象的引用不能指向不一樣的對象。可是 final 對象裏的數據能夠被改變。也就是說 final 對象的引用不能改變,可是裏面的值能夠改變。
final 修飾符一般和 static 修飾符一塊兒使用來建立類常量。
public class Test{ final int value = 10; // 下面是聲明常量的實例 public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; //將輸出一個錯誤 } }
類中的 final 方法能夠被子類繼承,可是不能被子類修改。
聲明 final 方法的主要目的是防止該方法的內容被修改。
以下所示,使用 final 修飾符聲明方法。
public class Test{ public final void changeName(){ // 方法體 } }
final 類不能被繼承,沒有類可以繼承 final 類的任何特性。
public final class Test { // 類體 }
抽象類:
抽象類不能用來實例化對象,聲明抽象類的惟一目的是爲了未來對該類進行擴充。
一個類不能同時被 abstract 和 final 修飾。若是一個類包含抽象方法,那麼該類必定要聲明爲抽象類,不然將出現編譯錯誤。
抽象類能夠包含抽象方法和非抽象方法。
abstract class Caravan{ private double price; private String model; private String year; public abstract void goFast(); //抽象方法 public abstract void changeColor(); }
抽象方法是一種沒有任何實現的方法,該方法的的具體實現由子類提供。
抽象方法不能被聲明成 final 和 static。
任何繼承抽象類的子類必須實現父類的全部抽象方法,除非該子類也是抽象類。
若是一個類包含若干個抽象方法,那麼該類必須聲明爲抽象類。抽象類能夠不包含抽象方法。
抽象方法的聲明以分號結尾,例如:public abstract sample();。
public abstract class SuperClass{ abstract void m(); //抽象方法 } class SubClass extends SuperClass{ //實現抽象方法 void m(){ ......... } }
synchronized 關鍵字聲明的方法同一時間只能被一個線程訪問。synchronized 修飾符能夠應用於四個訪問修飾符。
public synchronized void showDetails(){ ....... }
序列化的對象包含被 transient 修飾的實例變量時,java 虛擬機(JVM)跳過該特定的變量。
該修飾符包含在定義變量的語句中,用來預處理類和變量的數據類型。
public transient int limit = 55; // 不會持久化 public int b; // 持久化
volatile 修飾的成員變量在每次被線程訪問時,都強制從共享內存中從新讀取該成員變量的值。並且,當成員變量發生變化時,會強制線程將變化值回寫到共享內存。這樣在任什麼時候刻,兩個不一樣的線程老是看到某個成員變量的同一個值。
一個 volatile 對象引用多是 null。
public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) // 第一行 { // 代碼 } } public void stop() { active = false; // 第二行 } }
一般狀況下,在一個線程調用 run() 方法(在 Runnable 開啓的線程),在另外一個線程調用 stop() 方法。 若是 第一行 中緩衝區的 active 值被使用,那麼在 第二行 的 active 值爲 false 時循環不會中止。
可是以上代碼中咱們使用了 volatile 修飾 active,因此該循環會中止。
計算機的最基本用途之一就是執行數學運算,做爲一門計算機語言,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(區別詳見下文) |
下面的簡單示例程序演示了算術運算符。複製並粘貼下面的 Java 程序並保存爲 Test.java 文件,而後編譯並運行這個程序:
public class Test { public static void main(String[] args) { int a = 10; int b = 20; int c = 25; int d = 25; System.out.println("a + b = " + (a + b) ); System.out.println("a - b = " + (a - b) ); System.out.println("a * b = " + (a * b) ); System.out.println("b / a = " + (b / a) ); System.out.println("b % a = " + (b % a) ); System.out.println("c % a = " + (c % a) ); System.out.println("a++ = " + (a++) ); System.out.println("a-- = " + (a--) ); // 查看 d++ 與 ++d 的不一樣 System.out.println("d++ = " + (d++) ); System.out.println("++d = " + (++d) ); } }
以上實例編譯運行結果以下:
a++ = 10
a-- = 11
d++ = 25++d = 27
一、自增(++)自減(--)運算符是一種特殊的算術運算符,在算術運算符中須要兩個操做數來進行運算,而自增自減運算符是一個操做數。
public class selfAddMinus{ public static void main(String[] args){ int a = 3;//定義一個變量; int b = ++a;//自增運算 int c = 3; int d = --c;//自減運算 System.out.println("進行自增運算後的值等於"+b); System.out.println("進行自減運算後的值等於"+d); } }
運行結果爲:
進行自增運算後的值等於4進行自減運算後的值等於2
解析:
·
int b = ++a; 拆分運算過程爲: a=a+1=4; b=a=4, 最後結果爲b=4,a=4
·
·
int d = --c; 拆分運算過程爲: c=c-1=2; d=c=2, 最後結果爲d=2,c=2
·
二、前綴自增自減法(++a,--a): 先進行自增或者自減運算,再進行表達式運算。
三、後綴自增自減法(a++,a--): 先進行表達式運算,再進行自增或者自減運算 實例:
public class selfAddMinus{ public static void main(String[] args){ int a = 5;//定義一個變量; int b = 5; int x = 2*++a; int y = 2*b++; System.out.println("自增運算符前綴運算後a="+a+",x="+x); System.out.println("自增運算符後綴運算後b="+b+",y="+y); } }
運行結果爲:
自增運算符前綴運算後a=6,x=12自增運算符後綴運算後b=6,y=10
下表爲Java支持的關係運算符
表格中的實例整數變量A的值爲10,變量B的值爲20:
運算符 |
描述 |
例子 |
== |
檢查若是兩個操做數的值是否相等,若是相等則條件爲真。 |
(A == B)爲假(非真)。 |
!= |
檢查若是兩個操做數的值是否相等,若是值不相等則條件爲真。 |
(A != B) 爲真。 |
> |
檢查左操做數的值是否大於右操做數的值,若是是那麼條件爲真。 |
(A> B)非真。 |
< |
檢查左操做數的值是否小於右操做數的值,若是是那麼條件爲真。 |
(A <B)爲真。 |
>= |
檢查左操做數的值是否大於或等於右操做數的值,若是是那麼條件爲真。 |
(A> = B)爲假。 |
<= |
檢查左操做數的值是否小於或等於右操做數的值,若是是那麼條件爲真。 |
(A <= B)爲真。 |
下面的簡單示例程序演示了關係運算符。複製並粘貼下面的Java程序並保存爲Test.java文件,而後編譯並運行這個程序:
public class Test { public static void main(String[] args) { int a = 10; int b = 20; System.out.println("a == b = " + (a == b) ); System.out.println("a != b = " + (a != b) ); System.out.println("a > b = " + (a > b) ); System.out.println("a < b = " + (a < b) ); System.out.println("b >= a = " + (b >= a) ); System.out.println("b <= a = " + (b <= a) ); } }
以上實例編譯運行結果以下:
Java定義了位運算符,應用於整數類型(int),長整型(long),短整型(short),字符型(char),和字節型(byte)等類型。
位運算符做用在全部的位上,而且按位運算。假設a = 60,b = 13;它們的二進制格式表示將以下:
B = 0000 1101-----------------
A&b = 0000 1100
A ^ B = 0011 0001~A= 1100 0011
下表列出了位運算符的基本運算,假設整數變量A的值爲60和變量B的值爲13:
操做符 |
描述 |
例子 |
& |
若是相對應位都是1,則結果爲1,不然爲0 |
(A&B),獲得12,即0000 1100 |
| |
若是相對應位都是0,則結果爲0,不然爲1 |
(A | 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 |
下面的簡單示例程序演示了位運算符。複製並粘貼下面的Java程序並保存爲Test.java文件,而後編譯並運行這個程序:
public class Test { public static void main(String[] args) { int a = 60; /* 60 = 0011 1100 */ int b = 13; /* 13 = 0000 1101 */ int c = 0; c = a & b; /* 12 = 0000 1100 */ System.out.println("a & b = " + c ); c = a | b; /* 61 = 0011 1101 */ System.out.println("a | b = " + c ); c = a ^ b; /* 49 = 0011 0001 */ System.out.println("a ^ b = " + c ); c = ~a; /*-61 = 1100 0011 */ System.out.println("~a = " + c ); c = a << 2; /* 240 = 1111 0000 */ System.out.println("a << 2 = " + c ); c = a >> 2; /* 15 = 1111 */ System.out.println("a >> 2 = " + c ); c = a >>> 2; /* 15 = 0000 1111 */ System.out.println("a >>> 2 = " + c ); } }
以上實例編譯運行結果以下:
下表列出了邏輯運算符的基本運算,假設布爾變量A爲真,變量B爲假
操做符 |
描述 |
例子 |
&& |
稱爲邏輯與運算符。當且僅當兩個操做數都爲真,條件才爲真。 |
(A && B)爲假。 |
| | |
稱爲邏輯或操做符。若是任何兩個操做數任何一個爲真,條件爲真。 |
(A | | B)爲真。 |
! |
稱爲邏輯非運算符。用來反轉操做數的邏輯狀態。若是條件爲true,則邏輯非運算符將獲得false。 |
!(A && B)爲真。 |
下面的簡單示例程序演示了邏輯運算符。複製並粘貼下面的Java程序並保存爲Test.java文件,而後編譯並運行這個程序:
public class Test { public static void main(String[] args) { boolean a = true; boolean b = false; System.out.println("a && b = " + (a&&b)); System.out.println("a || b = " + (a||b) ); System.out.println("!(a && b) = " + !(a && b)); } }
以上實例編譯運行結果以下:
當使用與邏輯運算符時,在兩個操做數都爲true時,結果才爲true,可是當獲得第一個操做爲false時,其結果就一定是false,這時候就不會再判斷第二個操做了。
public class LuoJi{ public static void main(String[] args){ int a = 5;//定義一個變量; boolean b = (a<4)&&(a++<10); System.out.println("使用短路邏輯運算符的結果爲"+b); System.out.println("a的結果爲"+a); } }
運行結果爲:
使用短路邏輯運算符的結果爲false
a的結果爲5
解析: 該程序使用到了短路邏輯運算符(&&),首先判斷 a<4 的結果爲 false,則 b 的結果一定是 false,因此再也不執行第二個操做 a++<10 的判斷,因此 a 的值爲 5。
下面是Java語言支持的賦值運算符:
操做符 |
描述 |
例子 |
= |
簡單的賦值運算符,將右操做數的值賦給左側操做數 |
C = A + B將把A + B獲得的值賦給C |
+ = |
加和賦值操做符,它把左操做數和右操做數相加賦值給左操做數 |
C + = A等價於C = C + A |
- = |
減和賦值操做符,它把左操做數和右操做數相減賦值給左操做數 |
C - = A等價於C = C - |
* = |
乘和賦值操做符,它把左操做數和右操做數相乘賦值給左操做數 |
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 |
| = |
按位或賦值操做符 |
C | = 2等價於C = C | 2 |
面的簡單示例程序演示了賦值運算符。複製並粘貼下面的Java程序並保存爲Test.java文件,而後編譯並運行這個程序:
public class Test { public static void main(String[] args) { int a = 10; int b = 20; int c = 0; c = a + b; System.out.println("c = a + b = " + c ); c += a ; System.out.println("c += a = " + c ); c -= a ; System.out.println("c -= a = " + c ); c *= a ; System.out.println("c *= a = " + c ); a = 10; c = 15; c /= a ; System.out.println("c /= a = " + c ); a = 10; c = 15; c %= a ; System.out.println("c %= a = " + c ); c <<= 2 ; System.out.println("c <<= 2 = " + c ); c >>= 2 ; System.out.println("c >>= 2 = " + c ); c >>= 2 ; System.out.println("c >>= a = " + c ); c &= a ; System.out.println("c &= 2 = " + c ); c ^= a ; System.out.println("c ^= a = " + c ); c |= a ; System.out.println("c |= a = " + c ); } }
以上實例編譯運行結果以下:
條件運算符也被稱爲三元運算符。該運算符有3個操做數,而且須要判斷布爾表達式的值。該運算符的主要是決定哪一個值應該賦值給變量。
variable x = (expression) ? value if true : value if false
public class Test { public static void main(String[] args){ int a , b; a = 10; // 若是 a 等於 1 成立,則設置 b 爲 20,不然爲 30 b = (a == 1) ? 20 : 30; System.out.println( "Value of b is : " + b ); // 若是 a 等於 10 成立,則設置 b 爲 20,不然爲 30 b = (a == 10) ? 20 : 30; System.out.println( "Value of b is : " + b ); } }
以上實例編譯運行結果以下:
Value of b is : 30Value of b is : 20
該運算符用於操做對象實例,檢查該對象是不是一個特定類型(類類型或接口類型)。
instanceof運算符使用格式以下:
( Object reference variable ) instanceof (class/interface type)
若是運算符左側變量所指的對象,是操做符右側類或接口(class/interface)的一個對象,那麼結果爲真。
下面是一個例子:
String name = "James";boolean result = name instanceof String; // 因爲 name 是 String 類型,因此返回真
若是被比較的對象兼容於右側類型,該運算符仍然返回true。
看下面的例子:
class Vehicle {} public class Car extends Vehicle { public static void main(String[] args){ Vehicle a = new Car(); boolean result = a instanceof Car; System.out.println( result); } }
以上實例編譯運行結果以下:
true
當多個運算符出如今一個表達式中,誰先誰後呢?這就涉及到運算符的優先級別的問題。在一個多運算符的表達式中,運算符優先級不一樣會致使最後得出的結果差異甚大。
例如,(1+3)+(3+2)*2,這個表達式若是按加號最優先計算,答案就是 18,若是按照乘號最優先,答案則是 14。
再如,x = 7 + 3 * 2;這裏x獲得13,而不是20,由於乘法運算符比加法運算符有較高的優先級,因此先計算3 * 2獲得6,而後再加7。
下表中具備最高優先級的運算符在的表的最上面,最低優先級的在表的底部。
類別 |
操做符 |
關聯性 |
後綴 |
() [] . (點操做符) |
左到右 |
一元 |
+ + - !〜 |
從右到左 |
乘性 |
* /% |
左到右 |
加性 |
+ - |
左到右 |
移位 |
>> >>> << |
左到右 |
關係 |
>> = << = |
左到右 |
相等 |
== != |
左到右 |
按位與 |
& |
左到右 |
按位異或 |
^ |
左到右 |
按位或 |
| |
左到右 |
邏輯與 |
&& |
左到右 |
邏輯或 |
| | |
左到右 |
條件 |
?: |
從右到左 |
賦值 |
= + = - = * = / =%= >> = << =&= ^ = | = |
從右到左 |
逗號 |
, |
左到右 |
順序結構的程序語句只能被執行一次。若是您想要一樣的操做執行屢次,,就須要使用循環結構。
Java中有三種主要的循環結構:
· while 循環
· do…while 循環
· for 循環
在Java5中引入了一種主要用於數組的加強型for循環。
while是最基本的循環,它的結構爲:
while( 布爾表達式 ) { //循環內容 }
只要布爾表達式爲 true,循環體會一直執行下去。
public class Test { public static void main(String args[]) { int x = 10; while( x < 20 ) { System.out.print("value of x : " + x ); x++; System.out.print("\n"); } } }
以上實例編譯運行結果以下:
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
對於 while 語句而言,若是不知足條件,則不能進入循環。但有時候咱們須要即便不知足條件,也至少執行一次。
do…while 循環和 while 循環類似,不一樣的是,do…while 循環至少會執行一次。
do {
//代碼語句}while(布爾表達式);
注意:布爾表達式在循環體的後面,因此語句塊在檢測布爾表達式以前已經執行了。 若是布爾表達式的值爲 true,則語句塊一直執行,直到布爾表達式的值爲 false。
public class Test { public static void main(String args[]){ int x = 10; do{ System.out.print("value of x : " + x ); x++; System.out.print("\n"); }while( x < 20 ); } }
以上實例編譯運行結果以下:
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
雖然全部循環結構均可以用 while 或者 do...while表示,但 Java 提供了另外一種語句 —— for 循環,使一些循環結構變得更加簡單。
for循環執行的次數是在執行前就肯定的。語法格式以下:
for(初始化; 布爾表達式; 更新) { //代碼語句 }
關於 for 循環有如下幾點說明:
· 最早執行初始化步驟。能夠聲明一種類型,但可初始化一個或多個循環控制變量,也能夠是空語句。
· 而後,檢測布爾表達式的值。若是爲 true,循環體被執行。若是爲false,循環終止,開始執行循環體後面的語句。
· 執行一次循環後,更新循環控制變量。
· 再次檢測布爾表達式。循環執行上面的過程。
public class Test { public static void main(String args[]) { for(int x = 10; x < 20; x = x+1) { System.out.print("value of x : " + x ); System.out.print("\n"); } } }
以上實例編譯運行結果以下:
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
Java5 引入了一種主要用於數組的加強型 for 循環。
Java 加強 for 循環語法格式以下:
for(聲明語句 : 表達式) { //代碼句子 }
聲明語句:聲明新的局部變量,該變量的類型必須和數組元素的類型匹配。其做用域限定在循環語句塊,其值與此時數組元素的值相等。
表達式:表達式是要訪問的數組名,或者是返回值爲數組的方法。
public class Test { public static void main(String args[]){ int [] numbers = {10, 20, 30, 40, 50}; for(int x : numbers ){ System.out.print( x ); System.out.print(","); } System.out.print("\n"); String [] names ={"James", "Larry", "Tom", "Lacy"}; for( String name : names ) { System.out.print( name ); System.out.print(","); } } }
以上實例編譯運行結果以下:
10,20,30,40,50,James,Larry,Tom,Lacy,
break 主要用在循環語句或者 switch 語句中,用來跳出整個語句塊。
break 跳出最裏層的循環,而且繼續執行該循環下面的語句。
break 的用法很簡單,就是循環結構中的一條語句:
break;
public class Test { public static void main(String args[]) { int [] numbers = {10, 20, 30, 40, 50}; for(int x : numbers ) { // x 等於 30 時跳出循環 if( x == 30 ) { break; } System.out.print( x ); System.out.print("\n"); } } }
以上實例編譯運行結果以下:
1020
continue 適用於任何循環控制結構中。做用是讓程序馬上跳轉到下一次循環的迭代。
在 for 循環中,continue 語句使程序當即跳轉到更新語句。
在 while 或者 do…while 循環中,程序當即跳轉到布爾表達式的判斷語句。
continue 就是循環體中一條簡單的語句:
continue;
public class Test { public static void main(String args[]) { int [] numbers = {10, 20, 30, 40, 50}; for(int x : numbers ) { if( x == 30 ) { continue; } System.out.print( x ); System.out.print("\n"); } } }
以上實例編譯運行結果以下:
10204050
順序結構只能順序執行,不能進行判斷和選擇,所以須要分支結構。
Java 有兩種分支結構:
· if 語句
· switch 語句
一個 if 語句包含一個布爾表達式和一條或多條語句。
if 語句的用語法以下:
if(布爾表達式) { //若是布爾表達式爲true將執行的語句 }
若是布爾表達式的值爲 true,則執行 if 語句中的代碼塊,不然執行 if 語句塊後面的代碼。
public class Test { public static void main(String args[]){ int x = 10; if( x < 20 ){ System.out.print("這是 if 語句"); } } }
以上代碼編譯運行結果以下:
這是 if 語句
if 語句後面能夠跟 else 語句,當 if 語句的布爾表達式值爲 false 時,else 語句塊會被執行。
if…else 的用法以下:
if(布爾表達式){ //若是布爾表達式的值爲true }else{ //若是布爾表達式的值爲false }
public class Test { public static void main(String args[]){ int x = 30; if( x < 20 ){ System.out.print("這是 if 語句"); }else{ System.out.print("這是 else 語句"); } } }
以上代碼編譯運行結果以下:
這是 else 語句
if 語句後面能夠跟 elseif…else 語句,這種語句能夠檢測到多種可能的狀況。
使用 if,else if,else 語句的時候,須要注意下面幾點:
· if 語句至多有 1 個 else 語句,else 語句在全部的 elseif 語句以後。
· if 語句能夠有若干個 elseif 語句,它們必須在 else 語句以前。
· 一旦其中一個 else if 語句檢測爲 true,其餘的 else if 以及 else 語句都將跳過執行。
if...else 語法格式以下:
if(布爾表達式 1){ //若是布爾表達式 1的值爲true執行代碼 }else if(布爾表達式 2){ //若是布爾表達式 2的值爲true執行代碼 }else if(布爾表達式 3){ //若是布爾表達式 3的值爲true執行代碼 }else { //若是以上布爾表達式都不爲true執行代碼 }
public class Test { public static void main(String args[]){ int x = 30; if( x == 10 ){ System.out.print("Value of X is 10"); }else if( x == 20 ){ System.out.print("Value of X is 20"); }else if( x == 30 ){ System.out.print("Value of X is 30"); }else{ System.out.print("這是 else 語句"); } } }
以上代碼編譯運行結果以下:
Value of X is 30
使用嵌套的 if…else 語句是合法的。也就是說你能夠在另外一個 if 或者 elseif 語句中使用 if 或者 elseif 語句。
嵌套的 if…else 語法格式以下:
if(布爾表達式 1){ ////若是布爾表達式 1的值爲true執行代碼 if(布爾表達式 2){ ////若是布爾表達式 2的值爲true執行代碼 } }
你能夠像 if 語句同樣嵌套 else if...else。
public class Test { public static void main(String args[]){ int x = 30; int y = 10; if( x == 30 ){ if( y == 10 ){ System.out.print("X = 30 and Y = 10"); } } } }
以上代碼編譯運行結果以下:
switch 語句判斷一個變量與一系列值中某個值是否相等,每一個值稱爲一個分支。
switch 語法格式以下:
switch(expression){ case value : //語句 break; //可選 case value : //語句 break; //可選 //你能夠有任意數量的case語句 default : //可選 //語句 }
switch 語句有以下規則:
·
switch 語句中的變量類型能夠是: byte、short、int 或者 char。從 Java SE 7 開始,switch 支持字符串類型了,同時 case 標籤必須爲字符串常量或字面量。
·
·
switch 語句能夠擁有多個 case 語句。每一個 case 後面跟一個要比較的值和冒號。
·
·
case 語句中的值的數據類型必須與變量的數據類型相同,並且只能是常量或者字面常量。
·
·
當變量的值與 case 語句的值相等時,那麼 case 語句以後的語句開始執行,直到 break 語句出現纔會跳出 switch 語句。
·
·
當遇到 break 語句時,switch 語句終止。程序跳轉到 switch 語句後面的語句執行。case 語句沒必要需要包含 break 語句。若是沒有 break 語句出現,程序會繼續執行下一條 case 語句,直到出現 break 語句。
·
·
switch 語句能夠包含一個 default 分支,該分支必須是 switch 語句的最後一個分支。default 在沒有 case 語句的值和變量值相等的時候執行。default 分支不須要 break 語句。
·
public class Test { public static void main(String args[]){ //char grade = args[0].charAt(0); 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); } }
以上代碼編譯運行結果以下:
良好你的等級是 C
通常地,當須要使用數字的時候,咱們一般使用內置數據類型,如:byte、int、long、double 等。
int a = 5000; float b = 13.65f; byte c = 0x4a;
然而,在實際開發過程當中,咱們常常會遇到須要使用對象,而不是內置數據類型的情形。爲了解決這個問題,Java 語言爲每個內置數據類型提供了對應的包裝類。
全部的包裝類(Integer、Long、Byte、Double、Float、Short)都是抽象類 Number 的子類。
這種由編譯器特別支持的包裝稱爲裝箱,因此當內置數據類型被看成對象使用的時候,編譯器會把內置類型裝箱爲包裝類。類似的,編譯器也能夠把一個對象拆箱爲內置類型。Number 類屬於 java.lang 包。
下面是一個使用 Integer 對象的實例:
public class Test{ public static void main(String args[]){ Integer x = 5; x = x + 10; System.out.println(x); } }
以上實例編譯運行結果以下:
15
當 x 被賦爲整型值時,因爲x是一個對象,因此編譯器要對x進行裝箱。而後,爲了使x能進行加運算,因此要對x進行拆箱。
Java 的 Math 包含了用於執行基本數學運算的屬性和方法,如初等指數、對數、平方根和三角函數。
Math 的方法都被定義爲 static 形式,經過 Math 類能夠在主函數中直接調用。
public class Test { public static void main (String []args) { System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2)); System.out.println("0度的餘弦值:" + Math.cos(0)); System.out.println("60度的正切值:" + Math.tan(Math.PI/3)); System.out.println("1的反正切值: " + Math.atan(1)); System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2)); System.out.println(Math.PI); } }
以上實例編譯運行結果以下:
90 度的正弦值:1.00度的餘弦值:1.060度的正切值:1.73205080756887671的反正切值: 0.7853981633974483π/2的角度值:90.03.141592653589793
下面的表中列出的是 Number & Math 類經常使用的一些方法:
序號 |
方法與描述 |
1 |
xxxValue() |
2 |
compareTo() |
3 |
equals() |
4 |
valueOf() |
5 |
toString() |
6 |
parseInt() |
7 |
abs() |
8 |
ceil() |
9 |
floor() |
10 |
rint() |
11 |
round() |
12 |
min() |
13 |
max() |
14 |
exp() |
15 |
log() |
16 |
pow() |
17 |
sqrt() |
18 |
sin() |
19 |
cos() |
20 |
tan() |
21 |
asin() |
22 |
acos() |
23 |
atan() |
24 |
atan2() |
25 |
toDegrees() |
26 |
toRadians() |
27 |
random() |
參數 |
Math.floor |
Math.round |
Math.ceil |
1.4 |
1 |
1 |
2 |
1.5 |
1 |
2 |
2 |
1.6 |
1 |
2 |
2 |
-1.4 |
-2 |
-1 |
-1 |
-1.5 |
-2 |
-1 |
-1 |
-1.6 |
-2 |
-2 |
-1 |
public class Main { public static void main(String[] args) { double[] nums = { 1.4, 1.5, 1.6, -1.4, -1.5, -1.6 }; for (double num : nums) { test(num); } } private static void test(double num) { System.out.println("Math.floor(" + num + ")=" + Math.floor(num)); System.out.println("Math.round(" + num + ")=" + Math.round(num)); System.out.println("Math.ceil(" + num + ")=" + Math.ceil(num)); } }
以上實例執行輸出結果爲:
Math.floor(1.4)=1.0Math.round(1.4)=1Math.ceil(1.4)=2.0Math.floor(1.5)=1.0Math.round(1.5)=2Math.ceil(1.5)=2.0Math.floor(1.6)=1.0Math.round(1.6)=2Math.ceil(1.6)=2.0Math.floor(-1.4)=-2.0Math.round(-1.4)=-1Math.ceil(-1.4)=-1.0Math.floor(-1.5)=-2.0Math.round(-1.5)=-1Math.ceil(-1.5)=-1.0Math.floor(-1.6)=-2.0Math.round(-1.6)=-2Math.ceil(-1.6)=-1.0
Character 類用於對單個字符進行操做。
Character 類在對象中包裝一個基本類型 char 的值
char ch = 'a'; // Unicode 字符表示形式 char uniChar = '\u039A'; // 字符數組 char[] charArray ={ 'a', 'b', 'c', 'd', 'e' };
然而,在實際開發過程當中,咱們常常會遇到須要使用對象,而不是內置數據類型的狀況。爲了解決這個問題,Java語言爲內置數據類型char提供了包裝類Character類。
Character類提供了一系列方法來操縱字符。你能夠使用Character的構造方法建立一個Character類對象,例如:
Character ch = new Character('a');
在某些狀況下,Java編譯器會自動建立一個Character對象。
例如,將一個char類型的參數傳遞給須要一個Character類型參數的方法時,那麼編譯器會自動地將char類型參數轉換爲Character對象。 這種特徵稱爲裝箱,反過來稱爲拆箱。
// 原始字符 'a' 裝箱到 Character 對象 ch 中 Character ch = 'a'; // 原始字符 'x' 用 test 方法裝箱 // 返回拆箱的值到 'c' char c = test('x');
前面有反斜槓(\)的字符表明轉義字符,它對編譯器來講是有特殊含義的。
下面列表展現了Java的轉義序列:
轉義序列 |
描述 |
\t |
在文中該處插入一個tab鍵 |
\b |
在文中該處插入一個後退鍵 |
\n |
在文中該處換行 |
\r |
在文中該處插入回車 |
\f |
在文中該處插入換頁符 |
\' |
在文中該處插入單引號 |
\" |
在文中該處插入雙引號 |
\\ |
在文中該處插入反斜槓 |
當打印語句遇到一個轉義序列時,編譯器能夠正確地對其進行解釋。
如下實例轉義雙引號並輸出:
public class Test { public static void main(String args[]) { System.out.println("訪問\"菜鳥教程!\""); } }
以上實例編譯運行結果以下:
訪問"菜鳥教程!"
下面是Character類的方法:
序號 |
方法與描述 |
1 |
isLetter() |
2 |
isDigit() |
3 |
isWhitespace() |
4 |
isUpperCase() |
5 |
isLowerCase() |
6 |
toUpperCase() |
7 |
toLowerCase() |
8 |
toString() |
對於方法的完整列表,請參考的 java.lang.Character API 規範。
字符串普遍應用 在Java 編程中,在 Java 中字符串屬於對象,Java 提供了 String 類來建立和操做字符串。
建立字符串最簡單的方式以下:
String greeting = "菜鳥教程";
在代碼中遇到字符串常量時,這裏的值是 "菜鳥教程"",編譯器會使用該值建立一個 String 對象。
和其它對象同樣,能夠使用關鍵字和構造方法來建立 String 對象。
String 類有 11 種構造方法,這些方法提供不一樣的參數來初始化字符串,好比提供一個字符數組參數:
public class StringDemo{ public static void main(String args[]){ char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'}; String helloString = new String(helloArray); System.out.println( helloString ); } }
以上實例編譯運行結果以下:
runoob
注意:String 類是不可改變的,因此你一旦建立了 String 對象,那它的值就沒法改變了(詳看筆記部分解析)。
若是須要對字符串作不少修改,那麼應該選擇使用 StringBuffer & StringBuilder 類。
用於獲取有關對象的信息的方法稱爲訪問器方法。
String 類的一個訪問器方法是 length() 方法,它返回字符串對象包含的字符數。
下面的代碼執行後,len變量等於14:
public class StringDemo { public static void main(String args[]) { String site = "www.runoob.com"; int len = site.length(); System.out.println( "菜鳥教程網址長度 : " + len ); } }
以上實例編譯運行結果以下:
菜鳥教程網址長度 : 14
String 類提供了鏈接兩個字符串的方法:
string1.concat(string2);
返回 string2 鏈接 string1 的新字符串。也能夠對字符串常量使用 concat() 方法,如:
"個人名字是 ".concat("Runoob");
更經常使用的是使用'+'操做符來鏈接字符串,如:
"Hello," + " runoob" + "!"
結果以下:
"Hello, runoob!"
下面是一個例子:
public class StringDemo { public static void main(String args[]) { String string1 = "菜鳥教程網址:"; System.out.println("一、" + string1 + "www.runoob.com"); } }
以上實例編譯運行結果以下:
咱們知道輸出格式化數字能夠使用 printf() 和 format() 方法。
String 類使用靜態方法 format() 返回一個String 對象而不是 PrintStream 對象。
String 類的靜態方法 format() 能用來建立可複用的格式化字符串,而不只僅是用於一次打印輸出。
以下所示:
System.out.printf("浮點型變量的值爲 " + "%f, 整型變量的值爲 " + " %d, 字符串變量的值爲 " + "is %s", floatVar, intVar, stringVar);
你也能夠這樣寫
String fs; fs = String.format("浮點型變量的值爲 " + "%f, 整型變量的值爲 " + " %d, 字符串變量的值爲 " + " %s", floatVar, intVar, stringVar);
下面是 String 類支持的方法,更多詳細,參看 Java String API 文檔:
當對字符串進行修改的時候,須要使用 StringBuffer 和 StringBuilder 類。
和 String 類不一樣的是,StringBuffer 和 StringBuilder 類的對象可以被屢次的修改,而且不產生新的未使用對象。
StringBuilder 類在 Java 5 中被提出,它和 StringBuffer 之間的最大不一樣在於 StringBuilder 的方法不是線程安全的(不能同步訪問)。
因爲 StringBuilder 相較於 StringBuffer 有速度優點,因此多數狀況下建議使用 StringBuilder 類。然而在應用程序要求線程安全的狀況下,則必須使用 StringBuffer 類。
public class Test{ public static void main(String args[]){ StringBuffer sBuffer = new StringBuffer("菜鳥教程官網:"); sBuffer.append("www"); sBuffer.append(".runoob"); sBuffer.append(".com"); System.out.println(sBuffer); } }
以上實例編譯運行結果以下:
菜鳥教程官網:www.runoob.com
如下是 StringBuffer 類支持的主要方法:
序號 |
方法描述 |
1 |
public StringBuffer append(String s) |
2 |
public StringBuffer reverse() |
3 |
public delete(int start, int end) |
4 |
public insert(int offset, int i) |
5 |
replace(int start, int end, String str) |
下面的列表裏的方法和 String 類的方法相似:
序號 |
方法描述 |
1 |
int capacity() |
2 |
char charAt(int index) |
3 |
void ensureCapacity(int minimumCapacity) |
4 |
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) |
5 |
int indexOf(String str) |
6 |
int indexOf(String str, int fromIndex) |
7 |
int lastIndexOf(String str) |
8 |
int lastIndexOf(String str, int fromIndex) |
9 |
int length() |
10 |
void setCharAt(int index, char ch) |
11 |
void setLength(int newLength) |
12 |
CharSequence subSequence(int start, int end) |
13 |
String substring(int start) |
14 |
String substring(int start, int end) |
15 |
String toString() |
數組對於每一門編程語言來講都是重要的數據結構之一,固然不一樣語言對數組的實現及處理也不盡相同。
Java 語言中提供的數組是用來存儲固定大小的同類型元素。
你能夠聲明一個數組變量,如 numbers[100] 來代替直接聲明 100 個獨立變量 number0,number1,....,number99。
本教程將爲你們介紹 Java 數組的聲明、建立和初始化,並給出其對應的代碼。
首先必須聲明數組變量,才能在程序中使用數組。下面是聲明數組變量的語法:
dataType[] arrayRefVar; // 首選的方法 或 dataType arrayRefVar[]; // 效果相同,但不是首選方法
注意: 建議使用 dataType[] arrayRefVar 的聲明風格聲明數組變量。 dataType arrayRefVar[] 風格是來自 C/C++ 語言 ,在Java中採用是爲了讓 C/C++ 程序員可以快速理解java語言。
下面是這兩種語法的代碼示例:
double[] myList; // 首選的方法 或 double myList[]; // 效果相同,但不是首選方法
Java語言使用new操做符來建立數組,語法以下:
arrayRefVar = new dataType[arraySize];
上面的語法語句作了兩件事:
· 1、使用 dataType[arraySize] 建立了一個數組。
· 2、把新建立的數組的引用賦值給變量 arrayRefVar。
數組變量的聲明,和建立數組能夠用一條語句完成,以下所示:
dataType[] arrayRefVar = new dataType[arraySize];
另外,你還能夠使用以下的方式建立數組。
dataType[] arrayRefVar = {value0, value1, ..., valuek};
數組的元素是經過索引訪問的。數組索引從 0 開始,因此索引值從 0 到 arrayRefVar.length-1。
下面的語句首先聲明瞭一個數組變量 myList,接着建立了一個包含 10 個 double 類型元素的數組,而且把它的引用賦值給 myList 變量。
public class TestArray { public static void main(String[] args) { // 數組大小 int size = 10; // 定義數組 double[] myList = new double[size]; myList[0] = 5.6; myList[1] = 4.5; myList[2] = 3.3; myList[3] = 13.2; myList[4] = 4.0; myList[5] = 34.33; myList[6] = 34.0; myList[7] = 45.45; myList[8] = 99.993; myList[9] = 11123; // 計算全部元素的總和 double total = 0; for (int i = 0; i < size; i++) { total += myList[i]; } System.out.println("總和爲: " + total); } }
以上實例輸出結果爲:
總和爲: 11367.373
下面的圖片描繪了數組 myList。這裏 myList 數組裏有 10 個 double 元素,它的下標從 0 到 9。
數組的元素類型和數組的大小都是肯定的,因此當處理數組元素時候,咱們一般使用基本循環或者 foreach 循環。
該實例完整地展現瞭如何建立、初始化和操縱數組:
public class TestArray { public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5}; // 打印全部數組元素 for (int i = 0; i < myList.length; i++) { System.out.println(myList[i] + " "); } // 計算全部元素的總和 double total = 0; for (int i = 0; i < myList.length; i++) { total += myList[i]; } System.out.println("Total is " + total); // 查找最大元素 double max = myList[0]; for (int i = 1; i < myList.length; i++) { if (myList[i] > max) max = myList[i]; } System.out.println("Max is " + max); } }
以上實例編譯運行結果以下:
1.92.93.43.5Total is 11.7Max is 3.5
JDK 1.5 引進了一種新的循環類型,被稱爲 foreach 循環或者增強型循環,它能在不使用下標的狀況下遍歷數組。
該實例用來顯示數組myList中的全部元素:
public class TestArray { public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5}; // 打印全部數組元素 for (double element: myList) { System.out.println(element); } } }
以上實例編譯運行結果以下:
數組能夠做爲參數傳遞給方法。
例如,下面的例子就是一個打印 int 數組中元素的方法:
public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } }
下面例子調用 printArray 方法打印出 3,1,2,6,4 和 2:
printArray(new int[]{3, 1, 2, 6, 4, 2});
public static int[] reverse(int[] list) { int[] result = new int[list.length]; for (int i = 0, j = result.length - 1; i < list.length; i++, j--) { result[j] = list[i]; } return result; }
以上實例中 result 數組做爲函數的返回值。
多維數組能夠當作是數組的數組,好比二維數組就是一個特殊的一維數組,其每個元素都是一個一維數組,例如:
String str[][] = new String[3][4];
1. 直接爲每一維分配空間,格式以下:
type arrayName = new type[arraylenght1][arraylenght2];
type 能夠爲基本數據類型和複合數據類型,arraylenght1 和 arraylenght2 必須爲正整數,arraylenght1 爲行數,arraylenght2 爲列數。
例如:
int a[][] = new int[2][3];
解析:
二維數組 a 能夠當作一個兩行三列的數組。
2. 從最高維開始,分別爲每一維分配空間,例如:
String s[][] = new String[2][]; s[0] = new String[2]; s[1] = new String[3]; s[0][0] = new String("Good"); s[0][1] = new String("Luck"); s[1][0] = new String("to"); s[1][1] = new String("you"); s[1][2] = new String("!");
解析:
s[0]=new String[2] 和 s[1]=new String[3] 是爲最高維分配引用空間,也就是爲最高維限制其能保存數據的最長的長度,而後再爲其每一個數組元素單獨分配空間 s0=new String("Good") 等操做。
對二維數組中的每一個元素,引用方式爲 arrayName[index1][index2],例如:
num[1][0];
java.util.Arrays 類能方便地操做數組,它提供的全部方法都是靜態的。
具備如下功能:
· 給數組賦值:經過 fill 方法。
· 對數組排序:經過 sort 方法,按升序。
· 比較數組:經過 equals 方法比較數組中元素值是否相等。
· 查找數組元素:經過 binarySearch 方法能對排序好的數組進行二分查找法操做。
具體說明請查看下錶:
序號 |
方法和說明 |
1 |
public static int binarySearch(Object[] a, Object key) |
2 |
public static boolean equals(long[] a, long[] a2) |
3 |
public static void fill(int[] a, int val) |
4 |
public static void sort(Object[] a) |
java.util 包提供了 Date 類來封裝當前的日期和時間。 Date 類提供兩個構造函數來實例化 Date 對象。
第一個構造函數使用當前日期和時間來初始化對象。
Date( )
第二個構造函數接收一個參數,該參數是從1970年1月1日起的毫秒數。
Date(long millisec)
Date對象建立之後,能夠調用下面的方法。
序號 |
方法和描述 |
1 |
boolean after(Date date) |
2 |
boolean before(Date date) |
3 |
Object clone( ) |
4 |
int compareTo(Date date) |
5 |
int compareTo(Object obj) |
6 |
boolean equals(Object date) |
7 |
long getTime( ) |
8 |
int hashCode( ) |
9 |
void setTime(long time) |
10 |
String toString( ) |
Java中獲取當前日期和時間很簡單,使用 Date 對象的 toString() 方法來打印當前日期和時間,以下所示:
import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 對象 Date date = new Date(); // 使用 toString() 函數顯示日期時間 System.out.println(date.toString()); } }
以上實例編譯運行結果以下:
Mon May 04 09:51:52 CDT 2013
Java使用如下三種方法來比較兩個日期:
· 使用 getTime() 方法獲取兩個日期(自1970年1月1日經歷的毫秒數值),而後比較這兩個值。
· 使用方法 before(),after() 和 equals()。例如,一個月的12號比18號早,則 new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回true。
· 使用 compareTo() 方法,它是由 Comparable 接口定義的,Date 類實現了這個接口。
SimpleDateFormat 是一個以語言環境敏感的方式來格式化和分析日期的類。SimpleDateFormat 容許你選擇任何用戶自定義日期時間格式來運行。例如:
import java.util.*; import java.text.*; public class DateDemo { public static void main(String args[]) { Date dNow = new Date( ); SimpleDateFormat ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); System.out.println("Current Date: " + ft.format(dNow)); } }
SimpleDateFormat ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
這一行代碼確立了轉換的格式,其中 yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是時、分、秒。
注意:有的格式大寫,有的格式小寫,例如 MM 是月份,mm 是分;HH 是 24 小時制,而 hh 是 12 小時制。
以上實例編譯運行結果以下:
Current Date: Wed 2016.11.09 at 08:23:19 AM UTC
時間模式字符串用來指定時間格式。在此模式中,全部的 ASCII 字母被保留爲模式字母,定義以下:
字母 |
描述 |
示例 |
G |
紀元標記 |
AD |
y |
四位年份 |
2001 |
M |
月份 |
July or 07 |
d |
一個月的日期 |
10 |
h |
A.M./P.M. (1~12)格式小時 |
12 |
H |
一天中的小時 (0~23) |
22 |
m |
分鐘數 |
30 |
s |
秒數 |
55 |
S |
毫秒數 |
234 |
E |
星期幾 |
Tuesday |
D |
一年中的日子 |
360 |
F |
一個月中第幾周的周幾 |
2 (second Wed. in July) |
w |
一年中第幾周 |
40 |
W |
一個月中第幾周 |
1 |
a |
A.M./P.M. 標記 |
PM |
k |
一天中的小時(1~24) |
24 |
K |
A.M./P.M. (0~11)格式小時 |
10 |
z |
時區 |
Eastern Standard Time |
' |
文字定界符 |
Delimiter |
" |
單引號 |
` |
printf 方法能夠很輕鬆地格式化時間和日期。使用兩個字母格式,它以 %t 開頭而且如下面表格中的一個字母結尾。
轉 換 符 |
說 明 |
示 例 |
c |
包括所有日期和時間信息 |
星期六 十月 27 14:21:20 CST 2007 |
F |
"年-月-日"格式 |
2007-10-27 |
D |
"月/日/年"格式 |
10/27/07 |
r |
"HH:MM:SS PM"格式(12時制) |
02:25:51 下午 |
T |
"HH:MM:SS"格式(24時制) |
14:28:16 |
R |
"HH:MM"格式(24時制) |
14:28 |
更多 printf 解析能夠參見:Java 格式化輸出 printf 例子
import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 對象 Date date = new Date(); //c的使用 System.out.printf("所有日期和時間信息:%tc%n",date); //f的使用 System.out.printf("年-月-日格式:%tF%n",date); //d的使用 System.out.printf("月/日/年格式:%tD%n",date); //r的使用 System.out.printf("HH:MM:SS PM格式(12時制):%tr%n",date); //t的使用 System.out.printf("HH:MM:SS格式(24時制):%tT%n",date); //R的使用 System.out.printf("HH:MM格式(24時制):%tR",date); } }
以上實例編譯運行結果以下:
所有日期和時間信息:星期一 九月 10 10:43:36 CST 2012 年-月-日格式:2012-09-10 月/日/年格式:09/10/12
HH:MM:SS PM格式(12時制):10:43:36 上午
HH:MM:SS格式(24時制):10:43:36
HH:MM格式(24時制):10:43
若是你須要重複提供日期,那麼利用這種方式來格式化它的每一部分就有點複雜了。所以,能夠利用一個格式化字符串指出要被格式化的參數的索引。
索引必須緊跟在%後面,並且必須以$結束。例如:
import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 對象 Date date = new Date(); // 使用toString()顯示日期和時間 System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", date); } }
以上實例編譯運行結果以下:
Due date: February 09, 2014
或者,你能夠使用 < 標誌。它代表先前被格式化的參數要被再次使用。例如:
import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 對象 Date date = new Date(); // 顯示格式化時間 System.out.printf("%s %tB %<te, %<tY", "Due date:", date); } }
以上實例編譯運行結果以下:
Due date: February 09, 2014
定義日期格式的轉換符能夠使日期經過指定的轉換符生成新字符串。這些日期轉換符以下所示:
import java.util.*; public class DateDemo { public static void main(String args[]) { Date date=new Date(); //b的使用,月份簡稱 String str=String.format(Locale.US,"英文月份簡稱:%tb",date); System.out.println(str); System.out.printf("本地月份簡稱:%tb%n",date); //B的使用,月份全稱 str=String.format(Locale.US,"英文月份全稱:%tB",date); System.out.println(str); System.out.printf("本地月份全稱:%tB%n",date); //a的使用,星期簡稱 str=String.format(Locale.US,"英文星期的簡稱:%ta",date); System.out.println(str); //A的使用,星期全稱 System.out.printf("本地星期的簡稱:%tA%n",date); //C的使用,年前兩位 System.out.printf("年的前兩位數字(不足兩位前面補0):%tC%n",date); //y的使用,年後兩位 System.out.printf("年的後兩位數字(不足兩位前面補0):%ty%n",date); //j的使用,一年的天數 System.out.printf("一年中的天數(即年的第幾天):%tj%n",date); //m的使用,月份 System.out.printf("兩位數字的月份(不足兩位前面補0):%tm%n",date); //d的使用,日(二位,不夠補零) System.out.printf("兩位數字的日(不足兩位前面補0):%td%n",date); //e的使用,日(一位不補零) System.out.printf("月份的日(前面不補0):%te",date); } }
輸出結果爲:
英文月份簡稱:May本地月份簡稱:五月英文月份全稱:May本地月份全稱:五月英文星期的簡稱:Thu本地星期的簡稱:星期四年的前兩位數字(不足兩位前面補0):20年的後兩位數字(不足兩位前面補0):17一年中的天數(即年的第幾天):124兩位數字的月份(不足兩位前面補0):05兩位數字的日(不足兩位前面補0):04月份的日(前面不補0):4
SimpleDateFormat 類有一些附加的方法,特別是parse(),它試圖按照給定的SimpleDateFormat 對象的格式化存儲來解析字符串。例如:
import java.util.*; import java.text.*; public class DateDemo { public static void main(String args[]) { SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); String input = args.length == 0 ? "1818-11-11" : args[0]; System.out.print(input + " Parses as "); Date t; try { t = ft.parse(input); System.out.println(t); } catch (ParseException e) { System.out.println("Unparseable using " + ft); } } }
以上實例編譯運行結果以下:
$ java DateDemo1818-11-11 Parses as Wed Nov 11 00:00:00 GMT 1818
$ java DateDemo 2007-12-012007-12-01 Parses as Sat Dec 01 00:00:00 GMT 2007
sleep()使當前線程進入停滯狀態(阻塞當前線程),讓出CPU的使用、目的是不讓當前線程獨自霸佔該進程所獲的CPU資源,以留必定時間給其餘線程執行的機會。
你可讓程序休眠一毫秒的時間或者到您的計算機的壽命長的任意段時間。例如,下面的程序會休眠3秒:
import java.util.*; public class SleepDemo { public static void main(String args[]) { try { System.out.println(new Date( ) + "\n"); Thread.sleep(1000*3); // 休眠3秒 System.out.println(new Date( ) + "\n"); } catch (Exception e) { System.out.println("Got an exception!"); } } }
以上實例編譯運行結果以下:
Thu Sep 17 10:20:30 CST 2015
Thu Sep 17 10:20:33 CST 2015
下面的一個例子代表如何測量時間間隔(以毫秒爲單位):
import java.util.*; public class DiffDemo { public static void main(String args[]) { try { long start = System.currentTimeMillis( ); System.out.println(new Date( ) + "\n"); Thread.sleep(5*60*10); System.out.println(new Date( ) + "\n"); long end = System.currentTimeMillis( ); long diff = end - start; System.out.println("Difference is : " + diff); } catch (Exception e) { System.out.println("Got an exception!"); } } }
以上實例編譯運行結果以下:
Fri Jan 08 09:48:47 CST 2016
Fri Jan 08 09:48:50 CST 2016
Difference is : 3019
咱們如今已經可以格式化並建立一個日期對象了,可是咱們如何才能設置和獲取日期數據的特定部分呢,好比說小時,日,或者分鐘? 咱們又如何在日期的這些部分加上或者減去值呢? 答案是使用Calendar 類。
Calendar類的功能要比Date類強大不少,並且在實現方式上也比Date類要複雜一些。
Calendar類是一個抽象類,在實際使用時實現特定的子類的對象,建立對象的過程對程序員來講是透明的,只須要使用getInstance方法建立便可。
Calendar c = Calendar.getInstance();//默認是當前日期
使用Calendar類表明特定的時間,須要首先建立一個Calendar的對象,而後再設定該對象中的年月日參數來完成。
//建立一個表明2009年6月12日的Calendar對象Calendar c1 = Calendar.getInstance();
c1.set(2009, 6 - 1, 12);
Calendar類中用如下這些常量表示不一樣的意義,jdk內的不少類其實都是採用的這種思想
常量 |
描述 |
Calendar.YEAR |
年份 |
Calendar.MONTH |
月份 |
Calendar.DATE |
日期 |
Calendar.DAY_OF_MONTH |
日期,和上面的字段意義徹底相同 |
Calendar.HOUR |
12小時制的小時 |
Calendar.HOUR_OF_DAY |
24小時制的小時 |
Calendar.MINUTE |
分鐘 |
Calendar.SECOND |
秒 |
Calendar.DAY_OF_WEEK |
星期幾 |
Set設置
如:
Calendar c1 = Calendar.getInstance();
調用:
public final void set(int year,int month,int date)
c1.set(2009, 6 - 1, 12);//把Calendar對象c1的年月日分別設這爲:200九、六、12
利用字段類型設置
若是隻設定某個字段,例如日期的值,則能夠使用以下set方法:
public void set(int field,int value)
把 c1對象表明的日期設置爲10號,其它全部的數值會被從新計算
c1.set(Calendar.DATE,10);
把c1對象表明的年份設置爲2008年,其餘的全部數值會被從新計算
c1.set(Calendar.YEAR,2008);
其餘字段屬性set的意義以此類推
Add設置
Calendar c1 = Calendar.getInstance();
把c1對象的日期加上10,也就是c1也就表示爲10天后的日期,其它全部的數值會被從新計算
c1.add(Calendar.DATE, 10);
把c1對象的日期減去10,也就是c1也就表示爲10天前的日期,其它全部的數值會被從新計算
c1.add(Calendar.DATE, -10);
其餘字段屬性的add的意義以此類推
Calendar c1 = Calendar.getInstance(); // 得到年份 int year = c1.get(Calendar.YEAR); // 得到月份 int month = c1.get(Calendar.MONTH) + 1; // 得到日期 int date = c1.get(Calendar.DATE); // 得到小時 int hour = c1.get(Calendar.HOUR_OF_DAY); // 得到分鐘 int minute = c1.get(Calendar.MINUTE); // 得到秒 int second = c1.get(Calendar.SECOND); // 得到星期幾(注意(這個與Date類是不一樣的):1表明星期日、2表明星期一、3表明星期二,以此類推) int day = c1.get(Calendar.DAY_OF_WEEK);
Calendar類實現了公曆日曆,GregorianCalendar是Calendar類的一個具體實現。
Calendar 的getInstance()方法返回一個默認用當前的語言環境和時區初始化的GregorianCalendar對象。GregorianCalendar定義了兩個字段:AD和BC。這是表明公曆定義的兩個時代。
下面列出GregorianCalendar對象的幾個構造方法:
序號 |
構造函數和說明 |
1 |
GregorianCalendar() |
2 |
GregorianCalendar(int year, int month, int date) |
3 |
GregorianCalendar(int year, int month, int date, int hour, int minute) |
4 |
GregorianCalendar(int year, int month, int date, int hour, int minute, int second) |
5 |
GregorianCalendar(Locale aLocale) |
6 |
GregorianCalendar(TimeZone zone) |
7 |
GregorianCalendar(TimeZone zone, Locale aLocale) |
這裏是GregorianCalendar 類提供的一些有用的方法列表:
序號 |
方法和說明 |
1 |
void add(int field, int amount) |
2 |
protected void computeFields() |
3 |
protected void computeTime() |
4 |
boolean equals(Object obj) |
5 |
int get(int field) |
6 |
int getActualMaximum(int field) |
7 |
int getActualMinimum(int field) |
8 |
int getGreatestMinimum(int field) |
9 |
Date getGregorianChange() |
10 |
int getLeastMaximum(int field) |
11 |
int getMaximum(int field) |
12 |
Date getTime() |
13 |
long getTimeInMillis() |
14 |
TimeZone getTimeZone() |
15 |
int getMinimum(int field) |
16 |
int hashCode() |
17 |
boolean isLeapYear(int year) |
18 |
void roll(int field, boolean up) |
19 |
void set(int field, int value) |
20 |
void set(int year, int month, int date) |
21 |
void set(int year, int month, int date, int hour, int minute) |
22 |
void set(int year, int month, int date, int hour, int minute, int second) |
23 |
void setGregorianChange(Date date) |
24 |
void setTime(Date date) |
25 |
void setTimeInMillis(long millis) |
26 |
void setTimeZone(TimeZone value) |
27 |
String toString() |
import java.util.*; public class GregorianCalendarDemo { public static void main(String args[]) { String months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int year; // 初始化 Gregorian 日曆 // 使用當前時間和日期 // 默認爲本地時間和時區 GregorianCalendar gcalendar = new GregorianCalendar(); // 顯示當前時間和日期的信息 System.out.print("Date: "); System.out.print(months[gcalendar.get(Calendar.MONTH)]); System.out.print(" " + gcalendar.get(Calendar.DATE) + " "); System.out.println(year = gcalendar.get(Calendar.YEAR)); System.out.print("Time: "); System.out.print(gcalendar.get(Calendar.HOUR) + ":"); System.out.print(gcalendar.get(Calendar.MINUTE) + ":"); System.out.println(gcalendar.get(Calendar.SECOND)); // 測試當前年份是否爲閏年 if(gcalendar.isLeapYear(year)) { System.out.println("當前年份是閏年"); } else { System.out.println("當前年份不是閏年"); } } }
以上實例編譯運行結果以下:
Date: Apr 22 2009Time: 11:25:27當前年份不是閏年
關於 Calender 類的完整列表,你能夠參考標準的 Java文檔。
正則表達式定義了字符串的模式。
正則表達式能夠用來搜索、編輯或處理文本。
正則表達式並不只限於某一種語言,可是在每種語言中有細微的差異。
一個字符串其實就是一個簡單的正則表達式,例如 Hello World 正則表達式匹配 "Hello World" 字符串。
.(點號)也是一個正則表達式,它匹配任何一個字符如:"a" 或 "1"。
下表列出了一些正則表達式的實例及描述:
正則表達式 |
描述 |
this is text |
匹配字符串 "this is text" |
this\s+is\s+text |
注意字符串中的 \s+。 匹配單詞 "this" 後面的 \s+ 能夠匹配多個空格,以後匹配 is 字符串,再以後 \s+ 匹配多個空格而後再跟上 text 字符串。 能夠匹配這個實例:this is text |
^\d+(\.\d+)? |
^ 定義了以什麼開始 \d+ 匹配一個或多個數字 ? 設置括號內的選項是可選的 \. 匹配 "." 能夠匹配的實例:"5", "1.5" 和 "2.21"。 |
Java 正則表達式和 Perl 的是最爲類似的。
java.util.regex 包主要包括如下三個類:
· Pattern 類:
pattern 對象是一個正則表達式的編譯表示。Pattern 類沒有公共構造方法。要建立一個 Pattern 對象,你必須首先調用其公共靜態編譯方法,它返回一個 Pattern 對象。該方法接受一個正則表達式做爲它的第一個參數。
·
· Matcher 類:
Matcher 對象是對輸入字符串進行解釋和匹配操做的引擎。與Pattern 類同樣,Matcher 也沒有公共構造方法。你須要調用 Pattern 對象的 matcher 方法來得到一個 Matcher 對象。
·
· PatternSyntaxException:
PatternSyntaxException 是一個非強制異常類,它表示一個正則表達式模式中的語法錯誤。
·
如下實例中使用了正則表達式 .*runoob.* 用於查找字符串中是否包了 runoob 子串:
import java.util.regex.*; class RegexExample1{ public static void main(String args[]){ String content = "I am noob " + "from runoob.com."; String pattern = ".*runoob.*"; boolean isMatch = Pattern.matches(pattern, content); System.out.println("字符串中是否包含了 'runoob' 子字符串? " + isMatch); } }
實例輸出結果爲:
字符串中是否包含了 'runoob' 子字符串? true
捕獲組是把多個字符當一個單獨單元進行處理的方法,它經過對括號內的字符分組來建立。
例如,正則表達式 (dog) 建立了單一分組,組裏包含"d","o",和"g"。
捕獲組是經過從左至右計算其開括號來編號。例如,在表達式((A)(B(C))),有四個這樣的組:
· ((A)(B(C)))
· (A)
· (B(C))
· (C)
能夠經過調用 matcher 對象的 groupCount 方法來查看錶達式有多少個分組。groupCount 方法返回一個 int 值,表示matcher對象當前有多個捕獲組。
還有一個特殊的組(group(0)),它老是表明整個表達式。該組不包括在 groupCount 的返回值中。
下面的例子說明如何從一個給定的字符串中找到數字串:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { public static void main( String args[] ){ // 按指定模式在字符串查找 String line = "This order was placed for QT3000! OK?"; String pattern = "(\\D*)(\\d+)(.*)"; // 建立 Pattern 對象 Pattern r = Pattern.compile(pattern); // 如今建立 matcher 對象 Matcher m = r.matcher(line); if (m.find( )) { System.out.println("Found value: " + m.group(0) ); System.out.println("Found value: " + m.group(1) ); System.out.println("Found value: " + m.group(2) ); System.out.println("Found value: " + m.group(3) ); } else { System.out.println("NO MATCH"); } } }
以上實例編譯運行結果以下:
Found value: This order was placed for QT3000! OK?Found value: This order was placed for QTFound value: 3000Found value: ! OK?
在其餘語言中,\\ 表示:我想要在正則表達式中插入一個普通的(字面上的)反斜槓,請不要給它任何特殊的意義。
在 Java 中,\\ 表示:我要插入一個正則表達式的反斜線,因此其後的字符具備特殊的意義。
因此,在其餘的語言中,一個反斜槓\就足以具備轉義的做用,而在正則表達式中則須要有兩個反斜槓才能被解析爲其餘語言中的轉義做用。也能夠簡單的理解在正則表達式中,兩個 \ 表明其餘語言中的一個 \,這也就是爲何表示一位數字的正則表達式是 \\d,而表示一個普通的反斜槓是 \\\\。
字符 |
說明 |
\ |
將下一字符標記爲特殊字符、文本、反向引用或八進制轉義符。例如,"n"匹配字符"n"。"\n"匹配換行符。序列"\\\\"匹配"\\","\\("匹配"("。 |
^ |
匹配輸入字符串開始的位置。若是設置了 RegExp 對象的 Multiline 屬性,^ 還會與"\n"或"\r"以後的位置匹配。 |
$ |
匹配輸入字符串結尾的位置。若是設置了 RegExp 對象的 Multiline 屬性,$ 還會與"\n"或"\r"以前的位置匹配。 |
* |
零次或屢次匹配前面的字符或子表達式。例如,zo* 匹配"z"和"zoo"。* 等效於 {0,}。 |
+ |
一次或屢次匹配前面的字符或子表達式。例如,"zo+"與"zo"和"zoo"匹配,但與"z"不匹配。+ 等效於 {1,}。 |
? |
零次或一次匹配前面的字符或子表達式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效於 {0,1}。 |
{n} |
n 是非負整數。正好匹配 n 次。例如,"o{2}"與"Bob"中的"o"不匹配,但與"food"中的兩個"o"匹配。 |
{n,} |
n 是非負整數。至少匹配 n 次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的全部 o。"o{1,}"等效於"o+"。"o{0,}"等效於"o*"。 |
{n,m} |
M 和 n 是非負整數,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的頭三個 o。'o{0,1}' 等效於 'o?'。注意:您不能將空格插入逗號和數字之間。 |
? |
當此字符緊隨任何其餘限定符(*、+、?、{n}、{n,}、{n,m})以後時,匹配模式是"非貪心的"。"非貪心的"模式匹配搜索到的、儘量短的字符串,而默認的"貪心的"模式匹配搜索到的、儘量長的字符串。例如,在字符串"oooo"中,"o+?"只匹配單個"o",而"o+"匹配全部"o"。 |
. |
匹配除"\r\n"以外的任何單個字符。若要匹配包括"\r\n"在內的任意字符,請使用諸如"[\s\S]"之類的模式。 |
(pattern) |
匹配 pattern 並捕獲該匹配的子表達式。能夠使用 $0…$9 屬性從結果"匹配"集合中檢索捕獲的匹配。若要匹配括號字符 ( ),請使用"\("或者"\)"。 |
(?:pattern) |
匹配 pattern 但不捕獲該匹配的子表達式,即它是一個非捕獲匹配,不存儲供之後使用的匹配。這對於用"or"字符 (|) 組合模式部件的狀況頗有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更經濟的表達式。 |
(?=pattern) |
執行正向預測先行搜索的子表達式,該表達式匹配處於匹配 pattern 的字符串的起始點的字符串。它是一個非捕獲匹配,即不能捕獲供之後使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。預測先行不佔用字符,即發生匹配後,下一匹配的搜索緊隨上一匹配以後,而不是在組成預測先行的字符後。 |
(?!pattern) |
執行反向預測先行搜索的子表達式,該表達式匹配不處於匹配 pattern 的字符串的起始點的搜索字符串。它是一個非捕獲匹配,即不能捕獲供之後使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。預測先行不佔用字符,即發生匹配後,下一匹配的搜索緊隨上一匹配以後,而不是在組成預測先行的字符後。 |
x|y |
匹配 x 或 y。例如,'z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。 |
[xyz] |
字符集。匹配包含的任一字符。例如,"[abc]"匹配"plain"中的"a"。 |
[^xyz] |
反向字符集。匹配未包含的任何字符。例如,"[^abc]"匹配"plain"中"p","l","i","n"。 |
[a-z] |
字符範圍。匹配指定範圍內的任何字符。例如,"[a-z]"匹配"a"到"z"範圍內的任何小寫字母。 |
[^a-z] |
反向範圍字符。匹配不在指定的範圍內的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"範圍內的任何字符。 |
\b |
匹配一個字邊界,即字與空格間的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。 |
\B |
非字邊界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。 |
\cx |
匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回車符。x 的值必須在 A-Z 或 a-z 之間。若是不是這樣,則假定 c 就是"c"字符自己。 |
\d |
數字字符匹配。等效於 [0-9]。 |
\D |
非數字字符匹配。等效於 [^0-9]。 |
\f |
換頁符匹配。等效於 \x0c 和 \cL。 |
\n |
換行符匹配。等效於 \x0a 和 \cJ。 |
\r |
匹配一個回車符。等效於 \x0d 和 \cM。 |
\s |
匹配任何空白字符,包括空格、製表符、換頁符等。與 [ \f\n\r\t\v] 等效。 |
\S |
匹配任何非空白字符。與 [^ \f\n\r\t\v] 等效。 |
\t |
製表符匹配。與 \x09 和 \cI 等效。 |
\v |
垂直製表符匹配。與 \x0b 和 \cK 等效。 |
\w |
匹配任何字類字符,包括下劃線。與"[A-Za-z0-9_]"等效。 |
\W |
與任何非單詞字符匹配。與"[^A-Za-z0-9_]"等效。 |
\xn |
匹配 n,此處的 n 是一個十六進制轉義碼。十六進制轉義碼必須正好是兩位數長。例如,"\x41"匹配"A"。"\x041"與"\x04"&"1"等效。容許在正則表達式中使用 ASCII 代碼。 |
\num |
匹配 num,此處的 num 是一個正整數。到捕獲匹配的反向引用。例如,"(.)\1"匹配兩個連續的相同字符。 |
\n |
標識一個八進制轉義碼或反向引用。若是 \n 前面至少有 n 個捕獲子表達式,那麼 n 是反向引用。不然,若是 n 是八進制數 (0-7),那麼 n 是八進制轉義碼。 |
\nm |
標識一個八進制轉義碼或反向引用。若是 \nm 前面至少有 nm 個捕獲子表達式,那麼 nm 是反向引用。若是 \nm前面至少有 n 個捕獲,則 n 是反向引用,後面跟有字符 m。若是兩種前面的狀況都不存在,則 \nm 匹配八進制值 nm,其中 n 和 m 是八進制數字 (0-7)。 |
\nml |
當 n 是八進制數 (0-3),m 和 l 是八進制數 (0-7) 時,匹配八進制轉義碼 nml。 |
\un |
匹配 n,其中 n 是以四位十六進制數表示的 Unicode 字符。例如,\u00A9 匹配版權符號 (©)。 |
根據 Java Language Specification 的要求,Java 源代碼的字符串中的反斜線被解釋爲 Unicode 轉義或其餘字符轉義。所以必須在字符串字面值中使用兩個反斜線,表示正則表達式受到保護,不被 Java 字節碼編譯器解釋。例如,當解釋爲正則表達式時,字符串字面值 "\b" 與單個退格字符匹配,而 "\\b" 與單詞邊界匹配。字符串字面值 "\(hello\)" 是非法的,將致使編譯時錯誤;要與字符串 (hello) 匹配,必須使用字符串字面值 "\\(hello\\)"。
索引方法提供了有用的索引值,精確代表輸入字符串中在哪能找到匹配:
序號 |
方法及說明 |
1 |
public int start() |
2 |
public int start(int group) |
3 |
public int end() |
4 |
public int end(int group) |
研究方法用來檢查輸入字符串並返回一個布爾值,表示是否找到該模式:
序號 |
方法及說明 |
1 |
public boolean lookingAt() |
2 |
public boolean find() |
3 |
public boolean find(int start) |
4 |
public boolean matches() |
替換方法是替換輸入字符串裏文本的方法:
序號 |
方法及說明 |
1 |
public Matcher appendReplacement(StringBuffer sb, String replacement) |
2 |
public StringBuffer appendTail(StringBuffer sb) |
3 |
public String replaceAll(String replacement) |
4 |
public String replaceFirst(String replacement) |
5 |
public static String quoteReplacement(String s) |
下面是一個對單詞 "cat" 出如今輸入字符串中出現次數進行計數的例子:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static final String REGEX = "\\bcat\\b"; private static final String INPUT = "cat cat cat cattie cat"; public static void main( String args[] ){ Pattern p = Pattern.compile(REGEX); Matcher m = p.matcher(INPUT); // 獲取 matcher 對象 int count = 0; while(m.find()) { count++; System.out.println("Match number "+count); System.out.println("start(): "+m.start()); System.out.println("end(): "+m.end()); } } }
以上實例編譯運行結果以下:
Match number 1
start(): 0end(): 3Match number 2
start(): 4end(): 7Match number 3
start(): 8end(): 11Match number 4
start(): 19end(): 22
能夠看到這個例子是使用單詞邊界,以確保字母 "c" "a" "t" 並不是僅是一個較長的詞的子串。它也提供了一些關於輸入字符串中匹配發生位置的有用信息。
Start 方法返回在之前的匹配操做期間,由給定組所捕獲的子序列的初始索引,end 方法最後一個匹配字符的索引加 1。
matches 和 lookingAt 方法都用來嘗試匹配一個輸入序列模式。它們的不一樣是 matches 要求整個序列都匹配,而lookingAt 不要求。
lookingAt 方法雖然不須要整句都匹配,可是須要從第一個字符開始匹配。
這兩個方法常常在輸入字符串的開始使用。
咱們經過下面這個例子,來解釋這個功能:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static final String REGEX = "foo"; private static final String INPUT = "fooooooooooooooooo"; private static final String INPUT2 = "ooooofoooooooooooo"; private static Pattern pattern; private static Matcher matcher; private static Matcher matcher2; public static void main( String args[] ){ pattern = Pattern.compile(REGEX); matcher = pattern.matcher(INPUT); matcher2 = pattern.matcher(INPUT2); System.out.println("Current REGEX is: "+REGEX); System.out.println("Current INPUT is: "+INPUT); System.out.println("Current INPUT2 is: "+INPUT2); System.out.println("lookingAt(): "+matcher.lookingAt()); System.out.println("matches(): "+matcher.matches()); System.out.println("lookingAt(): "+matcher2.lookingAt()); } }
以上實例編譯運行結果以下:
Current REGEX is: fooCurrent INPUT is: foooooooooooooooooCurrent INPUT2 is: ooooofoooooooooooo
lookingAt(): true
matches(): false
lookingAt(): false
replaceFirst 和 replaceAll 方法用來替換匹配正則表達式的文本。不一樣的是,replaceFirst 替換首次匹配,replaceAll 替換全部匹配。
下面的例子來解釋這個功能:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String REGEX = "dog"; private static String INPUT = "The dog says meow. " + "All dogs say meow."; private static String REPLACE = "cat"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); // get a matcher object Matcher m = p.matcher(INPUT); INPUT = m.replaceAll(REPLACE); System.out.println(INPUT); } }
以上實例編譯運行結果以下:
The cat says meow. All cats say meow.
Matcher 類也提供了appendReplacement 和 appendTail 方法用於文本替換:
看下面的例子來解釋這個功能:
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexMatches { private static String REGEX = "a*b"; private static String INPUT = "aabfooaabfooabfoob"; private static String REPLACE = "-"; public static void main(String[] args) { Pattern p = Pattern.compile(REGEX); // 獲取 matcher 對象 Matcher m = p.matcher(INPUT); StringBuffer sb = new StringBuffer(); while(m.find()){ m.appendReplacement(sb,REPLACE); } m.appendTail(sb); System.out.println(sb.toString()); } }
以上實例編譯運行結果以下:
-foo-foo-foo-
PatternSyntaxException 是一個非強制異常類,它指示一個正則表達式模式中的語法錯誤。
PatternSyntaxException 類提供了下面的方法來幫助咱們查看發生了什麼錯誤。
序號 |
方法及說明 |
1 |
public String getDescription() |
2 |
public int getIndex() |
3 |
public String getPattern() |
4 |
public String getMessage() |
在前面幾個章節中咱們常用到 System.out.println(),那麼它是什麼呢?
· println() 是一個方法。
· System 是系統類。
· out 是標準輸出對象。
這句話的用法是調用系統類 System 中的標準輸出對象 out 中的方法 println()。
Java方法是語句的集合,它們在一塊兒執行一個功能。
· 方法是解決一類問題的步驟的有序組合
· 方法包含於類或對象中
· 方法在程序中被建立,在其餘地方被引用
· 1. 使程序變得更簡短而清晰。
· 2. 有利於程序維護。
· 3. 能夠提升程序開發的效率。
· 4. 提升了代碼的重用性。
· 1.方法的名字的第一個單詞應以小寫字母做爲開頭,後面的單詞則用大寫字母開頭寫,不使用鏈接符。例如:addPerson。
· 2.下劃線可能出如今 JUnit 測試方法名稱中用以分隔名稱的邏輯組件。一個典型的模式是:test<MethodUnderTest>_<state>,例如 testPop_emptyStack。
通常狀況下,定義一個方法包含如下語法:
修飾符 返回值類型 方法名(參數類型 參數名){ ... 方法體 ... return 返回值; }
方法包含一個方法頭和一個方法體。下面是一個方法的全部部分:
· 修飾符:修飾符,這是可選的,告訴編譯器如何調用該方法。定義了該方法的訪問類型。
· 返回值類型 :方法可能會返回值。returnValueType 是方法返回值的數據類型。有些方法執行所需的操做,但沒有返回值。在這種狀況下,returnValueType 是關鍵字void。
· 方法名:是方法的實際名稱。方法名和參數表共同構成方法簽名。
· 參數類型:參數像是一個佔位符。當方法被調用時,傳遞值給參數。這個值被稱爲實參或變量。參數列表是指方法的參數類型、順序和參數的個數。參數是可選的,方法能夠不包含任何參數。
· 方法體:方法體包含具體的語句,定義該方法的功能。
如:
public static int age(int birthday){...}
參數能夠有多個:
static float interest(float principal, int year){...}
注意: 在一些其它語言中方法指過程和函數。一個返回非void類型返回值的方法稱爲函數;一個返回void類型返回值的方法叫作過程。
下面的方法包含 2 個參數 num1 和 num2,它返回這兩個參數的最大值。
/** 返回兩個整型變量數據的較大值 */ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; }
Java 支持兩種調用方法的方式,根據方法是否返回值來選擇。
當程序調用一個方法時,程序的控制權交給了被調用的方法。當被調用方法的返回語句執行或者到達方法體閉括號時候交還控制權給程序。
當方法返回一個值的時候,方法調用一般被當作一個值。例如:
int larger = max(30, 40);
若是方法返回值是void,方法調用必定是一條語句。例如,方法println返回void。下面的調用是個語句:
System.out.println("歡迎訪問菜鳥教程!");
下面的例子演示瞭如何定義一個方法,以及如何調用它:
public class TestMax { /** 主方法 */ public static void main(String[] args) { int i = 5; int j = 2; int k = max(i, j); System.out.println( i + " 和 " + j + " 比較,最大值是:" + k); } /** 返回兩個整數變量較大的值 */ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; } }
以上實例編譯運行結果以下:
這個程序包含 main 方法和 max 方法。main 方法是被 JVM 調用的,除此以外,main 方法和其它方法沒什麼區別。
main 方法的頭部是不變的,如例子所示,帶修飾符 public 和 static,返回 void 類型值,方法名字是 main,此外帶個一個 String[] 類型參數。String[] 代表參數是字符串數組。
本節說明如何聲明和調用一個 void 方法。
下面的例子聲明瞭一個名爲 printGrade 的方法,而且調用它來打印給定的分數。
public class TestVoidMethod { public static void main(String[] args) { printGrade(78.5); } public static void printGrade(double score) { if (score >= 90.0) { System.out.println('A'); } else if (score >= 80.0) { System.out.println('B'); } else if (score >= 70.0) { System.out.println('C'); } else if (score >= 60.0) { System.out.println('D'); } else { System.out.println('F'); } } }
以上實例編譯運行結果以下:
C
這裏printGrade方法是一個void類型方法,它不返回值。
一個void方法的調用必定是一個語句。 因此,它被在main方法第三行以語句形式調用。就像任何以分號結束的語句同樣。
調用一個方法時候須要提供參數,你必須按照參數列表指定的順序提供。
例如,下面的方法連續n次打印一個消息:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) { System.out.println(message); } }
下面的例子演示按值傳遞的效果。
該程序建立一個方法,該方法用於交換兩個變量。
public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("交換前 num1 的值爲:" + num1 + " ,num2 的值爲:" + num2); // 調用swap方法 swap(num1, num2); System.out.println("交換後 num1 的值爲:" + num1 + " ,num2 的值爲:" + num2); } /** 交換兩個變量的方法 */ public static void swap(int n1, int n2) { System.out.println("\t進入 swap 方法"); System.out.println("\t\t交換前 n1 的值爲:" + n1 + ",n2 的值:" + n2); // 交換 n1 與 n2的值 int temp = n1; n1 = n2; n2 = temp; System.out.println("\t\t交換後 n1 的值爲 " + n1 + ",n2 的值:" + n2); } }
以上實例編譯運行結果以下:
交換前 num1 的值爲:1 ,num2 的值爲:2
進入 swap 方法
交換前 n1 的值爲:1,n2 的值:2
交換後 n1 的值爲 2,n2 的值:1交換後 num1 的值爲:1 ,num2 的值爲:2
傳遞兩個參數調用swap方法。有趣的是,方法被調用後,實參的值並無改變。
上面使用的max方法僅僅適用於int型數據。但若是你想獲得兩個浮點類型數據的最大值呢?
解決方法是建立另外一個有相同名字但參數不一樣的方法,以下面代碼所示:
public static double max(double num1, double num2) { if (num1 > num2) return num1; else return num2; }
若是你調用max方法時傳遞的是int型參數,則 int型參數的max方法就會被調用;
若是傳遞的是double型參數,則double類型的max方法體會被調用,這叫作方法重載;
就是說一個類的兩個方法擁有相同的名字,可是有不一樣的參數列表。
Java編譯器根據方法簽名判斷哪一個方法應該被調用。
方法重載可讓程序更清晰易讀。執行密切相關任務的方法應該使用相同的名字。
重載的方法必須擁有不一樣的參數列表。你不能僅僅依據修飾符或者返回類型的不一樣來重載方法。
變量的範圍是程序中該變量能夠被引用的部分。
方法內定義的變量被稱爲局部變量。
局部變量的做用範圍從聲明開始,直到包含它的塊結束。
局部變量必須聲明才能夠使用。
方法的參數範圍涵蓋整個方法。參數其實是一個局部變量。
for循環的初始化部分聲明的變量,其做用範圍在整個循環。
但循環體內聲明的變量其適用範圍是從它聲明到循環體結束。它包含以下所示的變量聲明:
你能夠在一個方法裏,不一樣的非嵌套塊中屢次聲明一個具備相同的名稱局部變量,但你不能在嵌套塊內兩次聲明局部變量。
有時候你但願運行一個程序時候再傳遞給它消息。這要靠傳遞命令行參數給main()函數實現。
命令行參數是在執行程序時候緊跟在程序名字後面的信息。
下面的程序打印全部的命令行參數:
public class CommandLine { public static void main(String args[]){ for(int