零基礎 “入坑” Java--- 十六、字符串String 異常

文章目錄

  • 一、String
    • 1.字符串的不可變性
    • 2.字符串的修改
    • 3.StringBuilder和StringBuffer
    • 4.【字符串練習】
      • 4.1 字符串中的第一個唯一字符
      • 4.2 字符串最后一個單詞的長度
      • 4.3 驗證回文串
  • 二、異常
    • 1.初識異常
    • 2.異常的分類
    • 3.異常的處理
    • 4.異常處理流程總結
    • 5.自定義異常

在上一章節中,我們已經對String類型的 常用的方法進行了學習,String的知識不止于此。本章節,我們再來對String進行探究,并學習有關異常的知識。

一、String

1.字符串的不可變性

在之前對字符串的學習中,我們了解到 字符串是一種不可變對象,即字符串不能被修改。當我們對字符串進行操作時,都會生成一個新的字符串。

是什么原因導致字符串的不可變性的呢?我們來閱讀一下String類型的源碼:
在這里插入圖片描述
字符串不能修改的真正原因是因為:value被private修飾,在類外拿不到value的引用,并非是因為final。

2.字符串的修改

    public static void main(String[] args) {String s = "hello";//避免直接對String類型的對象進行修改,因為String的不可變性,所有的修改都會創建新對象,效率低s += " world";System.out.println(s);}

使用上面這種方法,雖然可以完成對字符串的修改,但是效率很低。

我們可以使用StringBuilder和StringBuffer對字符串進行修改。

3.StringBuilder和StringBuffer

StringBuilder和StringBuffer的大部分功能都是相同的,我們就以StringBuilder舉例:
在這里插入圖片描述
在這里插入圖片描述

    public static void main(String[] args) {//StringBuilder和StringBuffer功能類似StringBuilder stringBuilder = new StringBuilder();StringBuilder stringBuilder1 = new StringBuilder("666");//在原數據上進行修改,不會生成新的對象//String不可變,而StringBuilder和StringBuffer可變stringBuilder1.append(888);stringBuilder1.append("222");stringBuilder1.append(888).append(99.99);System.out.println(stringBuilder1);stringBuilder1.setCharAt(1, 'M');stringBuilder1.insert(1, "==");System.out.println(stringBuilder1);stringBuilder1.reverse();System.out.println(stringBuilder1);/*** String 和 StringBuilder并不能直接轉換,要想轉換:* 1.String 變 StringBuilder:利用StringBuilder構造方法 或 append方法*      構造方法:StringBuilder stringBuilder1 = new StringBuilder("666");* 2.StringBuilder 變 String:toString方法*/String str = stringBuilder1.toString();System.out.println(str);}

當我們需要頻繁修改字符串的內容時,建議使用StringBuilder和StringBuffer。

在使用StringBuilder和StringBuffer時我們也需要注意:String和StringBuilder并不能直接轉換。

有關字符串的知識我們已經了解的差不多了,接下來我們通過幾道習題嘗試運用一下學過的知識。

4.【字符串練習】

4.1 字符串中的第一個唯一字符

字符串中的第一個唯一字符

在這里插入圖片描述
解題思路:
在這里插入圖片描述
在這道題目中,有兩個點值得我們注意:

1.因為字符’a’對應的ASCII碼值為97,在申請數組時,為了節省空間,我們只申請26個,后續遍歷數組時,用字符對應的ASCII碼值 - ‘a’ 即可。
2.在第二次遍歷數組時,需要對字符串進行遍歷,尋找第一個只出現一次的字符,而不應對計數數組遍歷。

class Solution {public int firstUniqChar(String s) {//定義一個計數數組,下標分別對應 26個英文字母 - 'a'int[] array = new int[26];//遍歷字符串,將出現的字符在計數數組中對應的位置+1for (int i = 0; i < s.length(); i++) {char ch = s.charAt(i);array[ch - 'a']++;}//再次遍歷字符串,尋找字符在計數數組中是否為1//注意:遍歷字符串,不是遍歷計數數組!!!for (int i = 0; i < s.length(); i++) {char ch = s.charAt(i);if (array[ch - 'a'] == 1) {return i;}}return -1;}
}

4.2 字符串最后一個單詞的長度

字符串最后一個單詞的長度

在這里插入圖片描述

import java.util.Scanner;// 注意類名必須為 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的區別while (in.hasNext()) { // 注意 while 處理多個 caseString s = in.nextLine();String[] str = s.split(" ");String ss = str[str.length - 1];System.out.println(ss.length());}}
}

在這道題目中,我們使用了split方法對字符串進行分割,獲取最后一個單詞,計算最后一個單詞的長度即可。

4.3 驗證回文串

驗證回文串

在這里插入圖片描述
解題思路:
在這里插入圖片描述

class Solution {//判斷是否為合法字符public boolean isLegal(char ch) {if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z') {return true;}return false;}public boolean isPalindrome(String s) {//將所有大寫字符轉換為小寫字符s = s.toLowerCase();int left = 0;int right = s.length() - 1;//left < right:相遇結束循環while (left < right) {//left < right:防止越界while (left < right && !isLegal(s.charAt(left))) {left++;}while (left < right && !isLegal(s.charAt(right))) {right--;}//至此,left 和 right均為合法字符if (s.charAt(left) != s.charAt(right)) {return false;} else {left++;right--;}}//循環條件不滿足,結束循環,是回文串return true;}
}

在這道題目中,我們需要注意:最外層的while循環的"left < right"判斷的是結束條件,而內層的while循環的"left < right"是判斷是否越界(如:字符串中的字符 均為 非字母數字字符的情況)。

二、異常

1.初識異常

在Java中,將程序執行過程中發生的不正常的行為稱為異常。 在之前的學習中,我們也已經遇到過很多可能會出現異常的情況:

  • 算術異常:
    在這里插入圖片描述
  • 數組越界異常
    在這里插入圖片描述
  • 空指針異常
    在這里插入圖片描述

2.異常的分類

異常可能在編譯時發生,也可能在程序運行時發生,根據發生的時機不同,可以將異常分為:編譯時異常和運行時異常。

  • 編譯時異常:在程序編譯期間發生的異常,稱為編譯時異常,也稱為受查異常。
  • 運行時異常:在程序執行期間發生的異常,稱為運行時異常,也稱為非受查異常。RuntimeException及其子類對應的異常,均稱為運行時異常。

3.異常的處理

在Java中,對異常進行處理依賴于5個關鍵字:throw,try,catch,finally,throws。

  • try-catch捕獲異常

使用 try-catch 進行防御性編程:

    public static void main(String[] args) {try {//System.out.println(10 / 0);int[] array1 = new int[]{1,2,3};//System.out.println(array1[6]);int[] array = null;System.out.println(array.length);} catch (ArithmeticException e) {System.out.println("捕獲算術異常");} catch (ArrayIndexOutOfBoundsException e) {System.out.println("數組越界異常");} catch (NullPointerException e) {System.out.println("空指針異常");}}

將可能會出現異常的代碼放在try的代碼塊中,使用catch匹配異常,當try中的代碼出現異常時,就會尋找catch的匹配條件,如果滿足,就會進入到對應的catch語句中。

try-catch 還可以與 finally 一起使用:

    public static void main(String[] args) {try {System.out.println(10 / 0);} catch (ArithmeticException e) { //catch需捕獲到對應的異常,否則程序依舊異常終止e.printStackTrace(); //打印異常信息System.out.println("捕獲異常");return;} finally {//finally中的代碼一定會被執行,哪怕之前的代碼中存在returnSystem.out.println("finally一定被執行");//不建議在finally中使用return語句}System.out.println("666");}

在使用 try - catch - finally 對異常進行捕獲時,我們需要注意:

1.try代碼塊中,對于拋出異常位置之后的代碼均不會執行。
2.如果拋出的異常的類型與catch的異常類型不匹配,則不會捕捉到異常,程序就會報錯。
3.使用try-catch語句成功捕捉到異常之后,try-catch后的代碼可以正常執行。
4.finally中的代碼一定會被執行,哪怕之前的代碼中存在return;不建議在finally中使用return語句,如果finally中和 try或catch 中均存在return語句,則執行finally中的return語句。
5.可以使用"printStackTrace"打印異常信息。

當多個異常的處理方式相同時,可以合并寫為:

    public static void main(String[] args) {try {//System.out.println(10 / 0);int[] array1 = new int[]{1,2,3};System.out.println(array1[6]);int[] array = null;System.out.println(array.length);} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {System.out.println("捕獲異常");} catch (NullPointerException e) {System.out.println("空指針異常");}}

Exception是所有異常的父類,當異常的處理具有父子關系時,一定是子類異常在前,父類異常在后,否則會報錯:

    public static void main(String[] args) {try {//System.out.println(10 / 0);int[] array1 = new int[]{1,2,3};System.out.println(array1[6]);int[] array = null;System.out.println(array.length);} catch (NullPointerException e) {System.out.println("空指針異常");} catch (Exception e) {System.out.println("異常");}}

也可以通過Exception捕獲所有異常,但并不推薦,捕獲到的異常太模糊。


  • throw拋出異常
    在Java中,可以借助throw關鍵字,拋出一個指定的異常對象:
    //通過throws拋出異常,交給調用者處理(JVM)public static void main1(String[] args) throws CloneNotSupportedException {int a = 10;if (a == 10) {//throw 常用于拋出自定義異常throw new CloneNotSupportedException("a == 10"); //編譯時異常}}

注意事項:

throw:
1.throw必須寫在方法體內部。
2.通過throw拋出的對象必須是Exception或Exception的子類。
3.如果拋出的對象是RuntimeException或RuntimeException的子類,則可以不用自己處理,交給JVM處理。
4.如果拋出的是編譯時異常,則必須用戶自己處理,否則編譯不通過。
5.異常一旦拋出,其后的代碼均不會執行。


throws:
1.throws用于處理編譯時異常,當用戶不想處理方法中的編譯時異常時,就可以通過throws將異常拋給方法的調用者處理。即當前方法不處理異常,提醒方法的調用者處理異常。
2.throws必須跟在方法的參數列表之后。
3.聲明的異常必須是Exception或Exception的子類。
4.如果方法內部拋出了多個異常,throws之后必須跟多個異常類型,多個異常類型之間用","隔開;如果拋出的多個異常類型之間具有父子關系,也可以直接聲明父類。
5.當調用聲明拋出異常的方法時,調用者必須對該異常進行處理,或者繼續使用throws拋出。


throw 和 throws:
當通過throw拋出一個運行時異常時,無需進行處理;但如果拋出的是一個編譯時異常,就需要對其進行處理,最簡單的方式就是通過throws處理。

4.異常處理流程總結

在這里插入圖片描述

5.自定義異常

在我們進行自定義異常之前,我們先來看看異常的源碼是怎樣的(以算術異常為例):
在這里插入圖片描述
自定義異常實現方式:

1.自定義一個類,并讓其繼承Exception或者RuntimeException,成為異常類。
2.實現一個帶有String參數類型的構造方法,參數為出現異常的原因。

我們仿照源碼編寫自定義異常:

//運行時異常(非受查異常):extends RuntimeException
public class myException extends RuntimeException{public myException() {}public myException(String message) {super(message);}
}

此時我們就編寫好了一個自定義的運行時異常。

使用也很簡單:

    //運行時異常不用throwspublic static void main(String[] args) {int a = 10;if (a == 10) {throw new myException("我的異常");}}

我們再來編寫一個自定義的編譯時異常:

//編譯時異常(受查異常):extends Exception
public class my_Exception extends Exception{public my_Exception() {}public my_Exception(String message) {super(message);}
}

使用編譯時異常:

    //編譯時異常必須throwspublic static void main1(String[] args) throws my_Exception {int a = 10;if (a == 10) {throw new my_Exception("我的異常");}}

由上面兩個自定義異常的例子我們可以得出:

1.自定義異常通常繼承Exception或者RuntimeException。
2.繼承Exception的異常類默認是受查異常。
3.繼承RuntimeException的異常類默認是非受查異常。


Ending。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917335.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917335.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917335.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

梯度下降在大模型訓練中的作用與實現

梯度下降&#xff08;Gradient Descent&#xff09;是深度學習中最核心的優化算法之一。大模型&#xff08;如GPT、BERT&#xff09;在訓練時需要優化數十億甚至上千億的參數&#xff0c;而梯度下降及其變體&#xff08;如SGD、Adam&#xff09;正是實現這一優化的關鍵工具。它…

【JVS更新日志】開源框架、APS排產、企業計劃、物聯網、邏輯引擎7.30更新說明!

項目介紹 JVS是企業級數字化服務構建的基礎腳手架&#xff0c;主要解決企業信息化項目交付難、實施效率低、開發成本高的問題&#xff0c;采用微服務配置化的方式&#xff0c;提供了低代碼數據分析物聯網的核心能力產品&#xff0c;并構建了協同辦公、企業常用的管理工具等&…

Eclipse中導入新項目,右鍵項目沒有Run on Server,Tomcat的add and remove找不到項目

原因分析沒有勾選Dynamic Web Module、Java、JavaScriptDynamic Web Module版本問題解決方法Eclipse中右鍵項目選擇Properties左側點擊project facets勾選Dynamic Web Module、Java、JavaScript&#xff0c;注意Dynamic Web Module版本問題,要和tomcat版本對應。- Dynamic Web …

IntelliJ IDEA 2025系列通用軟件安裝教程(Windows版)

前言 JetBrains系列開發工具&#xff08;如IntelliJ IDEA、PyCharm、WebStorm等&#xff09;是程序員們非常喜愛的集成開發環境。2025年最新版本帶來了更多強大的功能和改進。本教程將詳細介紹如何在Windows系統上安裝JetBrains 2025系列軟件。 最近挖到一個寶藏級人工智能學習…

烏鶇科技前端二面

1. 你能給我介紹一下你參與的重要項目&#xff0c;并重點介紹一下做的內容?通俗解釋&#xff1a; 挑一個你覺得最拿得出手、技術含量最高的項目&#xff0c;說說這個項目是干什么的&#xff08;比如一個電商網站、一個后臺管理系統&#xff09;&#xff0c;你在里面具體負責了…

《c++面向對象入門與實戰》筆記

前年的書&#xff0c;翻出來整理一下7章.指針指針 sizeof為4*指針 sizeof為 所指類型的sizeof注意free后置空&#xff0c;避免野指針11章.類

easyExcel生成多個sheet的動態表頭的實現

在使用 EasyExcel 實現“多個 Sheet 且每個 Sheet 表頭是動態的”需求時&#xff0c;思路如下&#xff1a;? 實現思路概述 EasyExcel 的 ExcelWriter 支持多個 Sheet 寫入。每個 Sheet&#xff1a; 使用 WriteSheet 創建&#xff1b;可以綁定一個動態生成的表頭 List<List&…

SQL 連接類型示例:內連接與外連接

SQL 連接類型示例&#xff1a;內連接與外連接 示例數據表 假設我們有兩個表&#xff1a; employees 表:emp_idemp_namedept_id1張三1012李四1023王五1034趙六NULLdepartments 表:dept_iddept_name101銷售部102技術部104財務部1. 內連接 (INNER JOIN) 內連接只返回兩個表中匹配的…

Ubuntu安裝gpu驅動,cuda

系統初始化 1、安裝基礎軟件 apt-get update apt-get -y install openssh-server openssh-client apt-utils freeipmi ipmitool sshpass ethtool zip unzip nano less git netplan.io iputils-ping mtr ipvsadm smartmontools python3-pip socat conntrack libvirt-clients li…

ctfshow_源碼壓縮包泄露

根據題目信息直接dirsearch解壓下來一個.txt文件&#xff0c;一個index.phpflag{flag_here}不對那么就去看index.php也沒有東西&#xff0c;于是查看wp發現是訪問/fl000g.txt這才是對的還有很多源碼泄露需要去了解? git源碼泄露? svn源碼泄露? DS_Store 文件泄露? 網站備份…

Python 程序設計講義(54):Python 的函數——函數概述

Python 程序設計講義&#xff08;54&#xff09;&#xff1a;Python 的函數——函數概述 目錄Python 程序設計講義&#xff08;54&#xff09;&#xff1a;Python 的函數——函數概述一、函數的類型1、內置函數2、自定義函數二、調用函數Python 提供了函數機制&#xff0c;把實…

學習Python中Selenium模塊的基本用法(3:下載瀏覽器驅動續)

前一篇文章主要介紹下載針對火狐瀏覽器的WebDriver&#xff0c;寫那篇文章時才找到能夠下最新版本Chrome的WebDriver地址&#xff08;參考文獻6&#xff09;&#xff0c;本文繼續學習并驗證針對Chrome瀏覽器的WebDriver下載和使用方法。Chrome的WebDriver版本與操作系統相關&am…

AIDL當Parcelable序列化的數據類通信時報“Class not found when unmarshalling“找不到該類時的解決方案

1. 報錯棧 &#xff1a;cusText這個類找不到 2 16:01:29.796 1044 5718 E Parcel : Class not found when unmarshalling: com.cus.sdk.cusText 08-02 16:01:29.796 1044 5718 E Parcel : java.lang.ClassNotFoundException: com.cus.sdk.cusText 08-02 16:01:29.796 1…

Django模型查詢與性能調優:告別N+1問題

文章目錄一、查詢基礎QuerySet 詳解一對多關聯查詢多對多關聯查詢二、N1查詢問題問題分析檢測方法解決方案三、高級查詢優化values()values_list()values()和values_list()對比Q() 對象復雜查詢查看生成的 SQL四、項目實戰場景實戰一、查詢基礎 QuerySet 詳解 Django 中通過模…

PyTorch 中 Tensor 統計學函數及相關概念

文章目錄PyTorch 中 Tensor 統計學函數及相關概念一、引言二、基礎統計學函數&#xff08;一&#xff09;torch.mean()——均值計算&#xff08;二&#xff09;torch.sum()——總和計算&#xff08;三&#xff09;torch.prod()——元素積計算&#xff08;四&#xff09;torch.m…

淺拷貝與深拷貝的區別

淺拷貝和深拷貝是兩種不同的對象復制方式&#xff0c;主要區別在于它們如何處理對象內部的引用類型字段。淺拷貝 (Shallow Copy)特點&#xff1a;只復制對象本身&#xff08;基本類型字段&#xff09;和對象中的引用&#xff08;地址&#xff09;不復制引用指向的實際對象原始對…

腳本統計MongoDB集合表數據量

腳本&#xff1a; #!/bin/bashipxxx.xx.xx.xx portxxxx dbxxxdb #user #passwmongo -host ${ip}:${port} <<EOF 2>/dev/null|grep -vE version|not match|session|compressors||Warning|delivers|upcoming|installation|https|switched|bye >collec use ${db}; sho…

圖漾AGV行業常用相機使用文檔

文章目錄1.圖漾相機設置IP1.1 前期準備2.FM851-E2相機2.1 FM851-E2適用場景2.2 FM851-E2 IO線和數據線定義2.2.1 IO接口定義2.2.2 數據接口線2.2.3 相機正面安裝方向2.2.4 相機IO指示燈2.3 FM851-E2/FM855-E2-7相機RGB顏色異常【解決措施1】&#xff1a;【解決措施2】&#xff…

電力系統分析學習筆記(二)- 標幺值計算與變壓器建模

電力系統分析學習筆記&#xff08;二&#xff09;- 標幺值計算與變壓器建模 1. 電力系統參數計算的基本原理 1.1 基本級的概念與選擇 基本級定義&#xff1a; 在多電壓等級的電力系統中&#xff0c;需要將所有參數歸算到同一個電壓等級這個統一的電壓等級稱為基本級 基本級選擇…

防火墻相關技術內容

防火墻的狀態檢測和會話技術一、防火墻的檢測機制早期包過濾防火墻采用逐包檢測機制&#xff0c;對每個報文獨立檢測其源地址、目的地址、端口等信息&#xff0c;根據預設規則決定轉發或丟棄。安全隱患&#xff1a;僅基于單包信息判斷&#xff0c;無法識別連接狀態。例如&#…