您现在的位置是:首页 > 编程 > 

【Java中常见的异常及其处理方式】

2025-07-29 11:00:27
【Java中常见的异常及其处理方式】 字符串修改的实现——StringBuilder和StringBuffer 通过查看Structure的结构我们可知:StringBuilder 的的方法基本上可以归为5种,分别是: append,delete,replace,insert,indexOf 其中最关键的是“append”,使用案例如下所示:代码语言:javascript代码运行次数:0运行

【Java中常见的异常及其处理方式】

字符串修改的实现——StringBuilder和StringBuffer

通过查看Structure的结构我们可知:StringBuilder 的的方法基本上可以归为5种,分别是: append,delete,replace,insert,indexOf 其中最关键的是“append”,使用案例如下所示:

代码语言:javascript代码运行次数:0运行复制
public class Main {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("12");
        stringBuffer.append("abc").append("excellent");
        println(stringBuffer);
        
        StringBuilder stringBuilder = new StringBuilder("Hi");
        stringBuilder.append(" Hello");
        stringBuilder.append(" Aileen ").append("How are you?");
        println(stringBuilder);
    }
}

通过查看StringBuffer和StringBuilder这两个方法的append方法的重写,我们可以得出:这两个方法最主要的区别如下:

  • 1. StringBuffer方法 : 有关键字synchronized【同步的】修饰,当它进入StringBuffer这个方法时,只有当这个方法里面的append执行完以后,才会执行其他方法的append,否则就不能执行其它对象的append,这意味着这个StringBuffer方法适用于多线程情况。(eg:多人排队上一个卫生间,只有当卫生间里面没人了下一个人才能进去上厕所。)
  • 2. StringBuilder方法 : 对于StringBulider方法,由于他没有synchronized这个关键字修饰,所以它适用于单线程情况下,若代码未涉及线程情况,选用StringBuilder即可。
  • 频繁上锁和解锁需要耗费系统资源。
  • . String变为StringBuilder: 利用StringBuilder的构造方法或append()方法。
  • 4. StringBuilder变为String: 调用toString方法。
代码语言:javascript代码运行次数:0运行复制
public class Main {
    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("12");
        stringBuffer.append("abc").append("excellent");
        println(stringBuffer);

        StringBuilder stringBuilder = new StringBuilder("Hi");
        stringBuilder.append(" Hello");
        stringBuilder.append(" Aileen ").append("How are you?");
        println(stringBuilder);

        println("=================================");
//        将stringBuilder转化成:string
        String str = ();
        println(str);

        println("----------------------------------");
        
//        将string转换成stringBuilder - 调用构造方法
        String str1 = "aileen";
        StringBuilder stringBuilder1 = new StringBuilder(str1);
        println(stringBuilder1);
        
        println("----------------------------------");
//
        StringBuilder stringBuilder2 = new StringBuilder();
        stringBuilder2.append(str1);
        println(stringBuilder2);
    }
}
  • 字符串不可改变的原因是因为这个数组是被private修饰的,并且未提供get()和set()方法

面试题

  • 1.String,StringBuffer,StringBuilder三者有什么区别?
    • String的内容不可修改,StringBuffer和StringBuilder的内容可修改。
    • StringBuffer与StringBuilder的大部分功能是相似的。
    • StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作。

异常

常见异常

①算数异常
②数组越界异常
代码语言:javascript代码运行次数:0运行复制
   public static void main(String[] args) {
        int[] array = {1,2,,4};
        println(array[10]);
        println("after");
    }
③空指针异常
代码语言:javascript代码运行次数:0运行复制
    public static void main(String[] args) {
        int[] array = null;
        println(array[10]);
        println("Hi");
    }

Error

代码语言:javascript代码运行次数:0运行复制
   public  static void func(){
        func();
    }

    public static void main(String[] args) {
        func();

    }

异常处理

throw - 抛出异常(一般是自定义的异常)
代码语言:javascript代码运行次数:0运行复制
    public static  void func2(int[] array){
        if(array == null){
            throw new ullPointerException("array == null 了!");
        }
    }
    public static void main(String[] args) {
        func2(null);
    }

异常一旦抛出,后面的代码就不会执行了。

异常捕获 - 两种方法:throws 和 try-catch
  • 在没有实现Cloneable接口的情况下,通过throws捕获异常
代码语言:javascript代码运行次数:0运行复制
class Person {
    public String name;

    @Override
    protected Object clone() throws CloneotSupportedException {
        return ();
    }
}

public class ExceptionLearn {


    public static void main(String[] args) throws CloneotSupportedException {
        Person p = new Person();
        Person p2 = (Person) ();

        println("hi");
    }
 }
  • 上面运行结果小结:如果程序的异常并未被程序员处理,此时这个异常就会交给JVM处理。程序会立即终止
  • 为了处理异常,我们加上Cloneable接口再次查看运行结果
在这里插入图片描述
  • 同一时刻,系统只能抛出一个异常。
    • 注意:
    • 必须跟在方法的参数列表后面
    • 2.声明的异常必须是Exception 或 Exception的子类
    • .方法内部如果抛出了多个异常,throws后必须跟多个异常类型,之间用逗号隔开,如果抛出的多个异常之间有父子关系,直接声明父类即可。
在这里插入图片描述
在这里插入图片描述

因为throws抛出的异常有两种情况,一种是运行时异常;另一种是编译时异常。 而对于main方法,他会把func()这里调用抛出的异常当做一个编译时异常来处理,这就需要程序员手动处理。以下是处理的方式及过程:

1.通过throws对异常进行层层声明,,然后程序会将异常交给JVM处理,此时程序就会异常终止。

在这里插入图片描述
在这里插入图片描述

2.通过try-catch抛出异常,用时程序还能够继续向下执行。如果不在main方法中throws Exception,可以通过快捷键Alt+Enter选中以下的内容。

在这里插入图片描述
代码语言:javascript代码运行次数:0运行复制
public class Test
{
    public static void func() throws ullPointerException{
        int[] array = null;
        println(array.length);
    }

    public static void main(String[] args){
        try {
            func();//将可能出现异常的代码放这
        } catch (ullPointerException e) {//捕获对应的异常
            println("处理异常");
        }
        println("after");
    }
}
在这里插入图片描述
  • 如果还想要具体的红报错信息可以通过调用空指针异常声明的变量e去调用printStackTrace方法来输出。
在这里插入图片描述

如果未在catch处声明对应代码的异常,再次运行程序结果会怎么样呢?

代码语言:javascript代码运行次数:0运行复制
    public static void main(String[] args) {

        try{
            int[] array = {1,2,,4,5};
            println(array[9]);
        }catch (ullPointerException e){
            e.printStackTrace();
            println("捕获到了空指针异常。。。");
        }
        println("after");
    }
在这里插入图片描述

通过上面的代码我们可以看出,如果我们没有将对应代码的异常通过catch去捕获,那么它就会通过我们的最后一道防线JVM去终止程序。

  • 现在让我们将对应代码的异常通过catch去捕获:
在这里插入图片描述

我们看到对于异常代码我们运行完以后直接通过catch去捕获其对应的异常,而对于异常代码后面的sout语句它并未执行。


  • 可以通过|分割捕获多个异常,但是缺点是无法知道具体是哪一个
代码语言:javascript代码运行次数:0运行复制
public static void main(String[] args) {
    try {
        int[] array = {1, 2, , 4, 5};
        println(array[9]);

    }catch (ullPointerException | ArrayIndexOutOfBoundsException e){  //可以通过|分割捕获多个异常,但是缺点是无法知道具体是哪一个
        e.printStackTrace();
        println("捕获到空指针 | 数组越界异常......");
    }
    println("Aileen");
}
在这里插入图片描述

  • 如果捕获的异常具有父子类关系情况下,要把父类放最后面
代码语言:javascript代码运行次数:0运行复制
    public static void main(String[] args) {
        int[] arr = {1,2,};
        try{
            println("before");
            arr = null;
            println(arr[100]);
            println("after");
        }catch(ullPointerException e){//空指针异常,属于异常的子类
            e.printStackTrace();
            println("我是空指针异常~");
        }
        catch(Exception e){//可捕获到所有异常,所有异常的父类
            e.printStackTrace();
        }
        println("after try catch");
    }
在这里插入图片描述
小结:

想要用try catch只是捕获简单的异常直接catchException即可,如果想要知道具体的异常类型可使用多个catch去捕获这个异常的具体内容


finally - 无论是否发生异常finally后面的语句都会被执行,用于关闭资源。

代码语言:javascript代码运行次数:0运行复制
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        try{
            int[] array = {1,2,,4};
            println(array[10]);

            int a = ();
            println(a);
        }catch (ullPointerException e){
            e.printStackTrace();
            println("捕获ullPointerException异常...");
        }catch (ArrayIndexOutOfBoundsException e){
            println("捕获ArrayIndexOutOfBoundsException异常...");
        }finally {
            println("finally被执行了");
            ();
        }
        println("after");
    }

代码语言:javascript代码运行次数:0运行复制
import java.util.Scanner;

public class Test {
    public static int func2() {
        Scanner scanner = new Scanner(System.in);
        try {
            int a = ();
            println(a);
        } catch (ullPointerException e) {
            e.printStackTrace();
            println("捕获ullPointerException异常...");
        } catch (ArrayIndexOutOfBoundsException e) {
            println("捕获ArrayIndexOutOfBoundsException异常...");
        } finally {
            println("finally被执行了");
            ();
        }
        println("after");

        return -1;
    }

    public static void main(String[] args) {
        func2();
    }

根据上面的运行结果可以得出以下结论:当我们try-catch捕获异常时,如果catch后面的异常跟我们出现的不匹配,它就会通过JVM来到异常,并且终止程序。上面的scanner需要我们输入数字但是我输入的是字符与需求不匹配,所以当程序运行到这里的时候会通过JVM去捕获异常,然后终止程序,finally永远都会被执行,正因如此如果我们需要关闭资源我们可以将关闭资源的代码放入到finally的语句块中,从而节省程序的资源


代码语言:javascript代码运行次数:0运行复制
import java.util.InputMismatchException;
import java.util.Scanner;

public class Test {
    public static int func2() {
        Scanner scanner = new Scanner(System.in);
        try {
            int a = 10;
            return a;
        } catch (InputMismatchException e) {
            e.printStackTrace();
            println("捕获InputMismatchException异常...");
        } finally {
            println("finally被执行了");
            ();
            return 99;
        }
    }

    public static void main(String[] args) {
        println(func2());
    }

异常处理流程梳理总结

  • 程序先执行try中的代码
  • 如果try中的代码出现异常,就会结束try中的代码,看和catch中的异常类型是否匹配。
  • 如果到匹配的异常类型,就会执行catch中的代码
  • 如果没有到匹配的异常类型,就会将异常向上传递到上层调用者。
  • 无论是否匹配到匹配的异常类型,finally中的代码都会被执行到(在该方法结束前执行)。
  • 如果上层调用者也没有处理的异常了,就继续向上传递。
  • 一直到main方法也没有合适的处理异常的代码,就会交给JVM来处理,此时程序就会异常终止。

自定义异常

代码语言:javascript代码运行次数:0运行复制
import java.util.InputMismatchException;
import java.util.Scanner;

class Login{
    public String userame = "Aileen";
    public String passWord = "12456";


    public  void logIn(String userame , String passWord){
        if(!this.(userame)){
            println("用户名错误!");
        }

        if(!this.(passWord)){
            println("密码错误!");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Login login = new Login();
        login.logIn("Aileen","abcd");

    }

我们可以通过自定义方法来到错误点但是无法定位到错误的位置,为了实现这个功能,我们可以自定义一个异常类,来定位错误,我们可以通过模仿已有的异常来编写自定义异常的类:

我们可以看到已有异常继承于运行时异常这个类,并且还调用了其无参构造方法和带有一个参数的构造方法。

  • 自定义异常可以继承Exception和RuntimeException
  • 通过关键字throw来抛出对应的自定义异常
代码语言:javascript代码运行次数:0运行复制
import java.util.InputMismatchException;
import java.util.Scanner;

class Login{
    public String userame = "Aileen";
    public String passWord = "12456";


    public  void logIn(String userame , String passWord){
        if(!this.(userame)){
//            println("用户名错误!");
            throw new UserameException("用户名错误!");
        }

        if(!this.(passWord)){
//            println("密码错误!");
            throw  new PassWordException("密码错误!");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        try{
            Login login = new Login();
            login.logIn("Aileen","abcd");
        }catch (UserameException e){
            e.printStackTrace();
            println("捕捉到了用户名错误异常。。。");
        }catch (PassWordException e){
            e.printStackTrace();
            println("捕捉到了密码错误异常。。。");
        }

        println("程序继续执行");

    }
  • 以下两个类是参照运行时异常的源代码修改的自定义异常代码:
    • ①.密码错误类
    • ②.用户名异常类

总结

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-12-19,如有侵权请联系 cloudcommunity@tencent 删除异常指针javasystem程序

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1239814.html

相关标签:无
上传时间: 2025-07-26 22:41:59
留言与评论(共有 9 条评论)
本站网友 双胞胎的形成
15分钟前 发表
本站网友 保持清醒
13分钟前 发表
StringBuffer
本站网友 海洋石油201
16分钟前 发表
但是缺点是无法知道具体是哪一个 e.printStackTrace(); println("捕获到空指针 | 数组越界异常......"); } println("Aileen"); }在这里插入图片描述如果捕获的异常具有父子类关系情况下
本站网友 帕科
19分钟前 发表
我们可以得出:这两个方法最主要的区别如下: 1. StringBuffer方法 : 有关键字synchronized【同步的】修饰
本站网友 物流业
26分钟前 发表
就继续向上传递
本站网友 飞扬电影城
3分钟前 发表
StringBuffer采用同步处理
本站网友 首创期货
18分钟前 发表
"); } println("after"); }在这里插入图片描述 通过上面的代码我们可以看出
本站网友 补肝汤
21分钟前 发表
此时程序就会异常终止