核心概述:本篇我們還是將繼續(xù)學(xué)習(xí)常用的API酸役,其中有用于一些基本數(shù)學(xué)運算的工具類Math、任意精度的整數(shù)BigInteger類、超大浮點數(shù)據(jù)BigDecimal涣澡;此外贱呐,在程序開發(fā)的過程中,我們常常會遇到各種各樣的異呈钏埽現(xiàn)象吼句,所以在本篇我們也將會學(xué)習(xí)認(rèn)識并處理java中的異常。
第一章:Math類
1.1-概述(了解)
java.lang.Math
類包含用于執(zhí)行基本數(shù)學(xué)運算的方法事格,如初等絕對值、四舍五入等搞隐。類似這樣的工具類驹愚,其所有方法均為靜態(tài)方法,并且不會創(chuàng)建對象劣纲,調(diào)用起來非常簡單逢捺。
1.2-常用方法(記憶)
方法
代碼
public static void main(String[] args) {
System.out.println(Math.abs(-100)); // 100
System.out.println(Math.ceil(10.1)); // 11.0
System.out.println(Math.floor(10.1)); // 10.0
}
第二章:BigInteger類
2.1-概述(了解)
java.math.BigInteger
類,不可變的任意精度的整數(shù)癞季。如果運算中劫瞳,數(shù)據(jù)的范圍超過了long類型后,可以使用BigInteger類實現(xiàn)绷柒,該類的計算整數(shù)是不限制長度的志于。
2.2-構(gòu)造方法(記憶)
BigInteger(String value)
將 BigInteger 的十進(jìn)制字符串表示形式轉(zhuǎn)換為 BigInteger。超過long類型的范圍废睦,已經(jīng)不能稱為數(shù)字了伺绽,因此構(gòu)造方法中采用字符串的形式來表示超大整數(shù),將超大整數(shù)封裝成BigInteger對象嗜湃。
2.3-常用方法(記憶)
方法
代碼
public static void main(String[] args){
BigInteger big1 = new BigInteger("987654321123456789000");
BigInteger big2 = new BigInteger("123456789987654321");
//加法運算
BigInteger add = big1.add(big2);
System.out.println("求和:"+add);
//減法運算
BigInteger sub = big1.subtract(big2);
System.out.println("求差:"+sub);
//乘法運算
BigInteger mul = big1.multiply(big2);
System.out.println("乘積:"+mul);
//除法運算
BigInteger div = big1.divide(big2);
System.out.println("除法:"+div);
}
第三章:BigDecimal類
3.1-概述(了解)
java.math.BigDecimal
類奈应,不可變的、任意精度的有符號十進(jìn)制數(shù)购披。該類可以實現(xiàn)超大浮點數(shù)據(jù)的精確運算杖挣。
3.2-構(gòu)造方法(記憶)
BigDecimal(String value)
將 BigDecimal的十進(jìn)制字符串表示形式轉(zhuǎn)換為 BigDecimal。
3.3-常用方法(記憶)
方法
divide方法
- BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)
- divesor:此 BigDecimal 要除以的值刚陡。
- scale:保留的位數(shù)
- roundingMode:舍入方式
- 舍入方式:BigDecimal類提供靜態(tài)的成員變量來表示舍入的方式
- BigDecimal.ROUND_UP 向上加1惩妇。
- BigDecimal.ROUND_DOWN 直接舍去。
- BigDecimal.ROUND_HALF_UP 四舍五入橘荠。
代碼
public static void main(String[] args){
BigDecimal big1 = new BigDecimal("5.25");
BigDecimal big2 = new BigDecimal("3.25");
//加法計算
BigDecimal add = big1.add(big2);
System.out.println("求和:"+add);
//減法計算
BigDecimal sub = big1.subtract(big2);
System.out.println("求差:"+sub);
//乘法計算
BigDecimal mul = big1.multiply(big2);
System.out.println("乘法:"+mul);
//除法計算
BigDecimal div = big1.divide(big2,2,BigDecimal.ROUND_HALF_UP);
System.out.println(div);
}
第四章:基本類型包裝類
4.1-概述(了解)
Java提供了兩個類型系統(tǒng)屿附,基本類型與引用類型,使用基本類型在于效率哥童,然而很多情況挺份,會創(chuàng)建對象使用,因為對象可以做更多的功能贮懈,如果想要我們的基本類型像對象一樣操作匀泊,就可以使用基本類型對應(yīng)的包裝類优训,如下:
4.2-Integer類(了解)
概述
包裝一個對象中的原始類型 int 的值。其構(gòu)造方法和靜態(tài)方法如下:
代碼
public static void main(String[] args) {
//public Integer(int value):根據(jù) int 值創(chuàng)建 Integer 對象(過時)
Integer i1 = new Integer(100);
System.out.println(i1);
//public Integer(String s):根據(jù) String 值創(chuàng)建 Integer 對象(過時)
Integer i2 = new Integer("100");
//Integer i2 = new Integer("abc"); //NumberFormatException
System.out.println(i2);
System.out.println("--------");
//public static Integer valueOf(int i):返回表示指定的 int 值的 Integer 實例
Integer i3 = Integer.valueOf(100);
System.out.println(i3);
//public static Integer valueOf(String s):返回一個保存指定值的Integer對象 String
Integer i4 = Integer.valueOf("100");
System.out.println(i4);
}
4.3-裝箱與拆箱(理解)
基本類型與對應(yīng)的包裝類對象之間各聘,來回轉(zhuǎn)換的過程稱為”裝箱“與”拆箱“:
- 裝箱:從基本類型轉(zhuǎn)換為對應(yīng)的包裝類對象揣非。
- 拆箱:從包裝類對象轉(zhuǎn)換為對應(yīng)的基本類型。
用Integer與 int為例:(看懂代碼即可)
基本數(shù)值---->包裝對象
Integer i = new Integer(4);//使用構(gòu)造函數(shù)函數(shù)
Integer iii = Integer.valueOf(4);//使用包裝類中的valueOf方法
包裝對象---->基本數(shù)值
int num = i.intValue();
4.4-自動裝箱與拆箱(理解)
由于我們經(jīng)常要做基本類型與包裝類之間的轉(zhuǎn)換躲因,從Java 5(JDK 1.5)開始早敬,基本類型與包裝類的裝箱、拆箱動作可以自動完成大脉。例如:
Integer i = 4;//自動裝箱搞监。相當(dāng)于Integer i = Integer.valueOf(4);
i = i + 5;//等號右邊:將i對象轉(zhuǎn)成基本數(shù)值(自動拆箱) i.intValue() + 5;
//加法運算完成后,再次裝箱镰矿,把基本數(shù)值轉(zhuǎn)成對象琐驴。
4.5-基本類型與字符串互相轉(zhuǎn)換(記憶)
基本類型轉(zhuǎn)String
轉(zhuǎn)換方式:
- 方式一:直接在數(shù)字后加一個空字符串
- 方式二:通過String類靜態(tài)方法valueOf()
示例代碼:
public static void main(String[] args) {
//int --- String
int number = 100;
//方式1
String s1 = number + "";
System.out.println(s1);
//方式2
//public static String valueOf(int i)
String s2 = String.valueOf(number);
System.out.println(s2);
}
String轉(zhuǎn)基本類型
除了Character類之外,其他所有包裝類都具有parseXxx靜態(tài)方法可以將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的基本類型:
-
public static byte parseByte(String s)
:將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的byte基本類型秤标。 -
public static short parseShort(String s)
:將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的short基本類型绝淡。 -
public static int parseInt(String s)
:將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的int基本類型。 -
public static long parseLong(String s)
:將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的long基本類型苍姜。 -
public static float parseFloat(String s)
:將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的float基本類型牢酵。 -
public static double parseDouble(String s)
:將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的double基本類型。 -
public static boolean parseBoolean(String s)
:將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的boolean基本類型怖现。
代碼:(以Integer為例)
public class Demo18WrapperParse {
public static void main(String[] args) {
int num = Integer.parseInt("100");
}
}
第五章:認(rèn)識異常
5.1-什么是異常(了解)
異常茁帽,就是不正常的意思。在生活中:醫(yī)生說,你的身體某個部位有異常,該部位和正常相比有點不同,該部位的功能將受影響.在程序中的意思就是:
- 異常 :指的是程序在執(zhí)行過程中屈嗤,出現(xiàn)的非正常的情況潘拨,最終會導(dǎo)致JVM的非正常停止。(因程序問題而中斷程序執(zhí)行的現(xiàn)象饶号。)
在Java等面向?qū)ο蟮木幊陶Z言中铁追,異常本身是一個類,產(chǎn)生異常就是創(chuàng)建異常對象并拋出了一個異常對象茫船。Java處理異常的方式是中斷處理琅束。
需要注意的是:異常指的并不是語法錯誤,語法錯了算谈,編譯不通過涩禀,不會產(chǎn)生字節(jié)碼文件,根本不能運行然眼。
5.2-異常體系(理解)
在Java中艾船,為了維護(hù)程序正常執(zhí)行,Java提供了處理異常的異常機(jī)制(異常類)。
在Java提供的異常機(jī)制中屿岂,其中java.lang.Throwable是根類践宴,而根類的派生類有java.lang.Error和java.lang.Excepiton兩個子類。
Error爷怀,錯誤(絕癥阻肩,比如:“癌癥”),該類型異常在程序中無法處理运授,只能盡量避免烤惊。
Excepiton,編譯期異常(寫源代碼時)(小毛病吁朦,比如:類似感冒)撕氧,該類型異常在程序中是可處理的。Excepiton類型還有一個子類RunTimeException喇完,表示運行期異常(程序運行的過程中),該類型異常在程序中也是可處理的剥啤。
為了更好的區(qū)分以上描述的異常分類锦溪,我們看以下程序。
// 【Error異掣樱】
// Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
// 內(nèi)存溢出刻诊。超出了分配給JVM內(nèi)存大小。
// 該程序只能修改源代碼解決問題牺丙。
int[]nums = new int[1024*1024*1024];
// 【Exception異吃蜓模】
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
// Unhandled exception: java.text.ParseException
// 此處在編寫源代碼時就發(fā)生異常,該異常后續(xù)可以通過相關(guān)的處理機(jī)制處理和避免
Date date = format.parse("2083-10-10");
// 【RunTimeException異吵宀荆】
int[] nums = {1,2,3};
// Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
// 在程序運行時出現(xiàn)的異常粟判,數(shù)組下標(biāo)超出。該異陈吞蓿可以通過相關(guān)異常機(jī)制處理
System.out.println(nums[4]);
5.3-異常產(chǎn)生的過程(理解)
在編程中档礁,為了更好的處理異常,我們首先要了解異常產(chǎn)生的過程吝沫。下面通過一段異常代碼來分析呻澜。
需求和代碼
// 需求:定義一個方法,用來獲取指定數(shù)組的指定位置的元素
public static void main(String[] args) {
int[]nums = {1,2,3};
System.out.println(getElement(nums,4));
}
public static int getElement(int[]arr,int index){
return arr[index];
}
分析
-
在執(zhí)行g(shù)etElement方法的過程中惨险,JVM檢測出數(shù)組索引越界異常羹幸,此時JVM會做兩件事:
- 創(chuàng)建一個ArrayIndexOutOfBoundsException異常對象,該對象中包含了異常的信息(內(nèi)容辫愉、原因栅受、位置)
- 因為getElment方法中沒有異常處理,JVM會把異常對象拋給getElment方法的調(diào)用處-main方法。
main方法接收到了ArrayIndexOutOfBoundsException異常對象窘疮,也沒有處理異常袋哼,則會把異常對象拋給JVM
-
JVM接收到了main方法后,會做兩件事:
- 在控制臺打印異常信息(內(nèi)容闸衫、原因涛贯、位置)
- 終止程序的執(zhí)行
圖解
第六章:處理異常
6.1-異常關(guān)鍵字(記憶)
try
catch
finally
throw
throws
6.2-拋出異常throw(理解)
概述
在編寫程序時,我們必須要考慮程序出現(xiàn)問題的情況蔚出。比如弟翘,在定義方法時,方法需要接受參數(shù)骄酗。那么稀余,當(dāng)調(diào)用方法使用接受到的參數(shù)時,首先需要先對參數(shù)數(shù)據(jù)進(jìn)行合法的判斷趋翻,數(shù)據(jù)若不合法睛琳,就應(yīng)該告訴調(diào)用者,傳遞合法的數(shù)據(jù)進(jìn)來踏烙。這時需要使用拋出異常的方式來告訴調(diào)用者师骗。
在java中,提供了一個throw關(guān)鍵字讨惩,它用來拋出一個指定的異常對象辟癌。那么,拋出一個異常具體如何操作呢荐捻?
- 創(chuàng)建一個異常對象黍少。封裝一些提示信息(信息可以自己編寫)。
- 需要將這個異常對象告知給調(diào)用者处面。怎么告知呢厂置?怎么將這個異常對象傳遞到調(diào)用者處呢?通過關(guān)鍵字throw就可以完成鸳君。
- throw用在方法內(nèi)农渊,用來拋出一個異常對象,將這個異常對象傳遞到調(diào)用者處或颊,并結(jié)束當(dāng)前方法的執(zhí)行砸紊。
使用格式
throw new 異常類名(參數(shù));
代碼演示
public static void main(String[] args) {
//創(chuàng)建一個數(shù)組
int[] arr = {2,4,52,2};
//根據(jù)索引找對應(yīng)的元素
int index = 4;
int element = getElement(arr, index);
System.out.println(element);
System.out.println("over");
}
/*
* 根據(jù) 索引找到數(shù)組中對應(yīng)的元素
*/
public static int getElement(int[] arr,int index){
//判斷 索引是否越界
if(index<0 || index>arr.length-1){
/*
判斷條件如果滿足,當(dāng)執(zhí)行完throw拋出異常對象后囱挑,方法已經(jīng)無法繼續(xù)運算醉顽。
這時就會結(jié)束當(dāng)前方法的執(zhí)行,并將異常告知給調(diào)用者平挑。這時就需要通過異常來解決游添。
*/
throw new ArrayIndexOutOfBoundsException("哥們系草,角標(biāo)越界了~~~");
}
int element = arr[index];
return element;
}
注意:如果產(chǎn)生了問題,我們就會throw將問題描述類即異常進(jìn)行拋出唆涝,也就是將問題返回給該方法的調(diào)用者找都。
那么對于調(diào)用者來說,該怎么處理呢廊酣?一種是進(jìn)行捕獲處理能耻,另一種就是繼續(xù)講問題聲明出去,使用throws聲明處理亡驰。
6.3-聲明異常throws(理解)
什么是聲明異常
將問題標(biāo)識出來晓猛,報告給調(diào)用者。如果方法內(nèi)通過throw拋出了編譯時異常凡辱,而沒有捕獲處理(稍后講解該方式)戒职,那么必須通過throws進(jìn)行聲明,讓調(diào)用者去處理透乾。
關(guān)鍵字throws運用于方法聲明之上,用于表示當(dāng)前方法不處理異常,而是提醒該方法的調(diào)用者來處理異常(拋出異常).
聲明異常格式
修飾符 返回值類型 方法名(參數(shù)) throws 異常類名1,異常類名2…{ }
聲明異常的代碼演示:
public static void main(String[] args) throws FileNotFoundException {
read("a.txt");
}
// 如果定義功能時有問題發(fā)生需要報告給調(diào)用者洪燥。可以通過在方法上使用throws關(guān)鍵字進(jìn)行聲明
public static void read(String path) throws FileNotFoundException {
if (!path.equals("a.txt")) {//如果不是 a.txt這個文件
// 我假設(shè) 如果不是 a.txt 認(rèn)為 該文件不存在 是一個錯誤 也就是異常 throw
throw new FileNotFoundException("文件不存在");
}
}
throws用于進(jìn)行異常類的聲明乳乌,若該方法可能有多種異常情況產(chǎn)生蚓曼,那么在throws后面可以寫多個異常類,用逗號隔開钦扭。
public static void main(String[] args) throws IOException {
read("a.txt");
}
public static void read(String path)throws FileNotFoundException, IOException {
if (!path.equals("a.txt")) {//如果不是 a.txt這個文件
// 我假設(shè) 如果不是 a.txt 認(rèn)為 該文件不存在 是一個錯誤 也就是異常 throw
throw new FileNotFoundException("文件不存在");
}
if (!path.equals("b.txt")) {
throw new IOException();
}
}
6.4-捕獲異常try…catch (記憶)
throws聲明異常的弊端是:異常后續(xù)代碼無法執(zhí)行(因為交給了JVM,JVM會終止程序)床绪。
try-catch可以讓調(diào)用者處理異常客情,并會繼續(xù)執(zhí)行后續(xù)程序。
try...catch格式
try{
編寫可能會出現(xiàn)異常的代碼
}catch(異常類型 e){
處理異常的代碼
//記錄日志/打印異常信息/繼續(xù)拋出異常
}
如何獲取異常信息
Throwable類中定義了一些查看方法:
public String getMessage()
:獲取異常的描述信息,原因(提示給用戶的時候,就提示錯誤原因癞己。public String toString()
:獲取異常的類型和異常描述信息(不用)膀斋。public void printStackTrace()
:打印異常的跟蹤棧信息并輸出到控制臺。
包含了異常的類型,異常的原因,還包括異常出現(xiàn)的位置,在開發(fā)和調(diào)試階段,都得使用printStackTrace痹雅。
代碼演示
// 需求:定義一個讀取文件的方法仰担,檢測文件的路徑和后綴名
public static void main(String[] args) {
try{
retFile("d.txt");
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("后續(xù)代碼");
/*
執(zhí)行結(jié)果:
java.io.IOException: 文件路徑錯誤
at it.leilei.cn.demo01.Main01.retFile(Main01.java:27)
at it.leilei.cn.demo01.Main01.main(Main01.java:12)
后續(xù)代碼
*/
}
// 讀取文件的方法
private static void retFile(String path) throws IOException {
// 如果后綴名不是.txt則拋出
if(!path.contains(".txt")){
throw new FileNotFoundException("文件后綴名不是.txt");
}
if(!path.contains("c:")) {
throw new IOException("文件路徑錯誤");
}
}
6.5-finally代碼塊(記憶)
為什么要使用finally代碼塊
finally:有一些特定的代碼無論異常是否發(fā)生,都需要執(zhí)行绩社。另外摔蓝,因為異常會引發(fā)程序跳轉(zhuǎn),導(dǎo)致有些語句執(zhí)行不到愉耙。而finally就是解決這個問題的贮尉,在finally代碼塊中存放的代碼都是一定會被執(zhí)行的。
什么時候的代碼必須最終執(zhí)行
當(dāng)我們在try語句塊中打開了一些物理資源(磁盤文件/網(wǎng)絡(luò)連接/數(shù)據(jù)庫連接等),我們都得在使用完之后,最終關(guān)閉打開的資源朴沿。
語法格式
try{
編寫可能會出現(xiàn)異常的代碼
}catch(異常類型 e){
處理異常的代碼
//記錄日志/打印異常信息/繼續(xù)拋出異常
}
...
finally{
// 代碼塊
}
代碼演示
// 需求:定義一個讀取文件的方法猜谚,檢測文件的路徑和后綴名
public static void main(String[] args) {
try{
retFile("d.txt");
}catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("釋放資源");
}
System.out.println("后續(xù)代碼");
}
// 讀取文件的方法
private static void retFile(String path) throws IOException {
// 如果后綴名不是.txt則拋出
if(!path.contains(".txt")){
throw new FileNotFoundException("文件后綴名不是.txt");
}
if(!path.contains("c:")) {
throw new IOException("文件路徑錯誤");
}
}
6.6-異常注意事項(了解)
注意事項
運行時異常被拋出可以不處理败砂。即不捕獲也不聲明拋出。
如果父類拋出了多個異常,子類覆蓋父類方法時,只能拋出相同的異澄呵Γ或者是他的子集昌犹。
父類方法沒有拋出異常,子類覆蓋父類該方法時也不可拋出異常览芳。此時子類產(chǎn)生該異常斜姥,只能捕獲處理,不能聲明拋出
當(dāng)多異常處理時路操,捕獲處理疾渴,前邊的類不能是后邊類的父類
在try/catch后可以追加finally代碼塊,其中的代碼一定會被執(zhí)行屯仗,通常用于資源回收搞坝。
-
多個異常使用捕獲又該如何處理呢?
- 多個異常分別處理魁袜。
- 多個異常一次捕獲桩撮,多次處理。
- 多個異常一次捕獲一次處理峰弹。
多個異常常用方式
try{
編寫可能會出現(xiàn)異常的代碼
}catch(異常類型A e){ 當(dāng)try中出現(xiàn)A類型異常,就用該catch來捕獲.
處理異常的代碼
//記錄日志/打印異常信息/繼續(xù)拋出異常
}catch(異常類型B e){ 當(dāng)try中出現(xiàn)B類型異常,就用該catch來捕獲.
處理異常的代碼
//記錄日志/打印異常信息/繼續(xù)拋出異常
}
第七章:自定義異常類
3.1 為什么要自定義異常類(了解)
? 我們說了Java中不同的異常類,分別表示著某一種具體的異常情況,那么在開發(fā)中總是有些異常情況是SUN沒有定義好的,此時我們根據(jù)自己業(yè)務(wù)的異常情況來定義異常類店量。例如年齡負(fù)數(shù)問題,考試成績負(fù)數(shù)問題等等。
3.2 什么是自定義異常類(了解)
? 在開發(fā)中根據(jù)自己業(yè)務(wù)的異常情況來定義異常類.
? 自定義一個業(yè)務(wù)邏輯異常: RegisterException鞠呈。一個注冊異常類融师。
3.3 如何定義異常類(記憶)
- 自定義一個編譯期異常: 自定義類 并繼承于 java.lang.Exception 。
- 自定義一個運行時期的異常類:自定義類 并繼承于 java.lang.RuntimeException 蚁吝。
3.4 代碼演示(練習(xí))
要求:我們模擬注冊操作旱爆,如果用戶名已存在,則拋出異常并提示:親窘茁,該用戶名已經(jīng)被注冊怀伦。
自定義異常類:
public class RegisterException extends Exception{
public RegisterException(){
super();
}
public RegisterException(String message){
super(message);
}
}
測試:
public static void main(String[] args) {
// 接收用戶注冊的用戶名
String name = new Scanner(System.in).next();
try{
check(name);
}catch (RegisterException e){
e.printStackTrace();
return;
}
System.out.println("注冊成功");
}
public static void check(String n) throws RegisterException{
String[]users={"張三","李四","王五"};
for (int i = 0; i < users.length; i++) {
if (n.equals( users[i])) {
throw new RegisterException("親,該用戶名已經(jīng)注冊");
}
}
}