汽车营销型网站建设,建设金融行业网站,腾讯云是做网站的吗,眉山市做网站的公司目录
前言#xff1a; Exceptions#xff08;异常#xff09;#xff1a;
异常的两大作用#xff1a;
异常的处理方式#xff1a;
1.JVM默认处理 2.自己捕获异常
3.抛出处理
自定义异常#xff1a;
异常的优点#xff1a;
总结#xff1a; 前言#xff1a; 前…
目录
前言 Exceptions异常
异常的两大作用
异常的处理方式
1.JVM默认处理 2.自己捕获异常
3.抛出处理
自定义异常
异常的优点
总结 前言 前文我们详细的为大家介绍了整个异常体系的框架本篇我们将为大家介绍Exceptions异常我们会讲解他的作用以及如何捕获这一篇很重要在搭建后端以及与前端交互的时候是一个很好用的技能因此我们即使不看本篇文章也一定要自己积极主动了解相关内容 Exceptions异常
在Java中异常Exceptions也是一种处理程序运行期间错误或异常情况的机制。异常是通过Java中的类来表示的这些类被称为异常类Exception Classes。
Java中的异常机制是基于“抛出和捕获”的原则。当程序出现异常的时候异常被创建并抛出throw然后在代码的其他地方被捕获catch并执行相应的处理逻辑。
Java中的异常类是从 java.lang.Exception 类派生出来的。异常类分为两类检查异常Checked Exceptions和非检查异常Unchecked Exceptions。
1. 检查异常 检查异常是指在代码中可能出现的特定情况需要显式处理。 检查异常必须在方法的声明中声明或者在方法体内通过try-catch语句块捕获。 例如IOException、FileNotFoundException等。
2. 非检查异常 非检查异常是指程序在运行时可能出现的异常情况。 非检查异常通常是由程序错误导致的如数组越界、除零错误等。 非检查异常无需在方法声明或方法体内捕获但可以选择捕获并进行处理。 例如NullPointerException、ArithmeticException等。
Java提供了多个关键字和语句来处理异常其中包括 try-catch语句用于捕获并处理异常。 throws关键字用于声明可能抛出的异常类型。 finally块用于定义无论是否出现异常都需要执行的代码。 throw关键字用于手动抛出异常。
通过合理地处理异常可以提高Java程序的健壮性和可靠性确保程序在异常情况下仍能正常运行。
异常的两大作用
1.异常是用来查询bug的关键参考信息。
假设你编写了一个处理用户登录的程序其中包括一个用户验证的功能。如果用户提供的用户名不存在你可能会抛出一个UserNotFoundException的异常。这个异常将包含有关错误的关键信息如用户名以便于在处理异常时进行调试和修复bug。
例如
public class UserLogin {public void validateUser(String username, String password) throws UserNotFoundException {// 在数据库中查找用户if (!userExists(username)) {throw new UserNotFoundException(用户名不存在 username);}// 进行密码验证等其他操作// ...}private boolean userExists(String username) {// 查询数据库判断用户是否存在// ...}// 其他代码
}
在上面的例子中如果用户提供的用户名在数据库中不存在该程序将抛出一个UserNotFoundException异常并传递包含错误信息的字符串。通过查看异常信息你可以追踪到出错的位置并在必要时修复bug例如检查数据库查询逻辑等。异常信息对于开发人员来说是非常有用的因为它们提供了有关bug发生位置和原因的重要线索。而我们以前还需要利用print手动输出一个“密码不存在”。 那为什么不选择打印报错呢 这是因为抛出异常是一种更为灵活和规范的做法。它提供了一种统一的异常处理机制使得调用者可以根据需要捕获和处理异常而不仅仅是简单地打印错误信息。异常还可以传递更详细的错误信息和上下文方便调用者进行更高级的错误处理逻辑。打印错误信息虽然简单直接但对于复杂的程序和错误处理需求来说可能不够灵活和可扩展。而且异常抛出之后程序就会直接停止执行而我们的print打印报错对于编译器来讲只是正常的执行了一条打印语句仍然会继续进行需要我们自己手动停止。 2.异常可以作为方法内部的一种特殊返回值用来告知调用者底层的执行情况。
public class FileProcessor {public void processFile(String fileName) throws FileProcessingException {try {// 打开文件进行处理openFile(fileName);// 其他处理逻辑// ...// 关闭文件closeFile();} catch (IOException e) {// 处理文件操作异常throw new FileProcessingException(文件处理发生异常, e);}}private void openFile(String fileName) throws IOException {// 打开文件的逻辑// ...}private void closeFile() throws IOException {// 关闭文件的逻辑// ...}
}
在上面的例子中FileProcessor类的processFile方法用于处理指定文件。如果在处理文件的过程中发生文件操作异常如文件无法打开、读取或关闭等它将抛出一个FileProcessingException异常并将底层的IOException作为原因传递给调用者。
通过这种方式调用者可以捕获并处理异常进一步了解底层执行情况比如是否成功打开和关闭文件。异常提供了一种机制允许将错误信息从方法的实现细节传递到方法的调用方使得调用者可以根据需要采取适当的措施。
异常作为方法内部的特殊返回值与其作为查询bug的关键参考信息之间的区别主要在于目的和使用方式。它们都提供了有关底层执行情况的信息在方法内部作为返回值时异常用于传达执行状态而在查询bug时异常信息用于诊断和调试错误的代码。
异常的处理方式
1.JVM默认处理
JVM默认的处理方式就是把异常的名称异常原因以及异常出现的位置等信息输出在控制台。而程序此时也会停止执行不会再进行下面的语句。
例如直接执行这段代码
public class test10 {public static void main(String[] args) {int[] arr new int[3];System.out.println(arr[4]); // 数组越界异常}
} 控制台就会输出 2.自己捕获异常
我们自己捕获异常就是利用try和catch语句自定义异常语句以及出现异常之后的执行策略。
格式为
try{
可能出现异常的代码
}
catch{
异常的处理代码
}
目的当代码出现异常的时候可以让程序继续往下执行。并不会像JVM默认处理的时候那样直接停止程序。
public class test10 {public static void main(String[] args) {try {int result divide(10, 0); // 调用自定义的除法方法System.out.println(结果 result);} catch (ArithmeticException e) { // 捕获特定类型的异常System.out.println(除数不能为零);e.printStackTrace(); // 打印堆栈跟踪}System.out.println(我可以被执行);}public static int divide(int dividend, int divisor) {return dividend / divisor; // 可能引发除零异常的除法操作}
}
执行结果为 try捕捉异常的三种情况
每个异常被不同的 catch 块捕获和处理在 try 块中的每个可能抛出异常的语句都有对应的 catch 块来捕获和处理该异常。这样可以根据不同的异常类型执行适当的处理逻辑。
try {// 可能抛出异常的语句1// 可能抛出异常的语句2// ...
} catch (ExceptionType1 e1) {// 处理异常类型1
} catch (ExceptionType2 e2) {// 处理异常类型2
} catch (ExceptionType3 e3) {// 处理异常类型3
}多个异常被同一个 catch 块捕获和处理如果多个异常属于同一个异常类型的子类型可以使用同一个 catch 块捕获和处理它们。这种情况下可以通过异常对象的属性或方法来区分和处理不同的子类型异常。
try {// 可能抛出异常的语句1// 可能抛出异常的语句2// ...
} catch (ParentExceptionType e) {// 处理多个异常类型
}异常被上层的 catch 块捕获如果在 try 块中的某个 catch 块成功捕获了一个异常且没有在其中抛出新的异常那么该异常会被视为已被处理并不会传递到下一个 catch 块。
try {// 可能抛出异常的语句1// 可能抛出异常的语句2// ...
} catch (ExceptionType1 e1) {// 处理异常类型1并不再传递异常
} catch (ExceptionType2 e2) {// 处理异常类型2
}如果我们tyr中的异常没有被捕获例如抛出了数组越界异常但是我们只写了判断空指针异常此时的异常就没有被catch捕获那么我们就会执行JVM的默认处理方式。
捕捉异常的注意点 1.如果我们要捕捉多个异常且这些异常中存在父子关系那么父类一定要在最下面 这么写是catch匹配异常是从上往下进行匹配的而父类异常可以接受所有的子类异常这就导致所有的异常走到父类异常这里都会被接受而后面的子类异常接收不到任何异常导致子类异常被父类异常接受可能无法得到我们想要的结果因此我们要把父类异常放到子类异常的最下面。 如果你想捕获所有可能抛出的异常可以使用Exception类作为catch块的参数。这样可以捕获到所有派生自Exception的异常。
try {// 可能抛出异常的语句
} catch (Exception e) {// 处理异常
}如果你想捕获特定类型的异常可以使用该异常类或其子类作为catch块的参数。
try {// 可能抛出异常的语句
} catch (ArithmeticException e) {// 处理算术异常
} catch (NullPointerException e) {// 处理空指针异常
} catch (IOException e) {// 处理输入输出异常
}catch (Exception e) {// 处理异常
}
通过掌握父类和子类之间的关系可以更有效地处理不同类型的异常并为程序提供适当的错误处理机制。 2.try中只要产生了一个异常try的剩下部分就会被跳过因此我们不可以在一个try中写多个异常语句这是没有用的只会执行第一个异常而我们写这么多的catch意义在于针对这一个异常我们要针对性的捕获它
public class test10 {public static void main(String[] args) {try {int[] numbers {1, 2, 3};System.out.println(numbers[4]); // 数组越界异常int result divide(10, 0); // 除零异常System.out.println(结果 result);} catch (ArrayIndexOutOfBoundsException e) {System.out.println(捕获到数组越界异常);e.printStackTrace();} catch (ArithmeticException e) {System.out.println(捕获到除零异常);e.printStackTrace();} catch (Exception e) {System.out.println(捕获到其他异常);e.printStackTrace();}System.out.println(异常处理完成);}public static int divide(int dividend, int divisor) {return dividend / divisor;}
}
执行结果 我们可以看到除零异常根本不会被捕获因为第一个数组越界异常发生以后try语句中的所有剩余都会被跳过。
手动捕获异常处理中的常见方法
Throwable 是Java中所有异常类的根类它定义了一些常用的方法可以在异常处理中使用。下面是一些常用的 Throwable 方法
getMessage()返回异常的详细描述信息。
try {// 可能抛出异常的代码
} catch (Exception e) {System.out.println(e.getMessage()); // 打印异常信息
}printStackTrace()将异常的跟踪栈信息输出到标准错误流System.err可以用于调试和定位异常发生的位置。
try {// 可能抛出异常的代码
} catch (Exception e) {e.printStackTrace(); // 输出异常跟踪栈信息
}getCause()返回导致当前异常的原因异常通常用于嵌套异常场景。
try {// 可能抛出异常的代码
} catch (Exception e) {Throwable cause e.getCause();if (cause ! null) {System.out.println(导致异常的原因 cause.getMessage());}
}getLocalizedMessage()返回异常本地化描述信息如果该异常类提供了本地化描述则返回本地化描述信息否则返回异常描述信息。
try {// 可能抛出异常的代码
} catch (Exception e) {System.out.println(e.getLocalizedMessage()); // 打印异常的本地化描述信息
}toString()返回异常的字符串表示包括异常类名和详细描述信息。
try {// 可能抛出异常的代码
} catch (Exception e) {System.out.println(e.toString()); // 打印异常的字符串表示
}这些是 Throwable 类的一些常用方法。需要注意的是Throwable 还有其他的方法和一些子类的特定方法可以根据需要进一步了解和使用。
3.抛出处理 throws
throws 关键字用于在方法声明中指定该方法可能抛出的异常类型。通过使用 throws 关键字可以将异常传递给调用者或上层代码来处理而不是在方法内部进行捕获和处理。
下面是一个使用 throws 的简单例子
import java.io.FileNotFoundException;
import java.io.FileReader;public class FileProcessor {public static void main(String[] args) {try {readFile(file.txt);} catch (FileNotFoundException e) {System.out.println(文件不存在);e.printStackTrace();}}public static void readFile(String fileName) throws FileNotFoundException {FileReader fileReader new FileReader(fileName);// 进行文件读取操作// ...}
}在上述代码中我们有一个 readFile 方法用于从指定的文件中读取内容。由于读取文件可能会发生文件不存在的异常因此在方法声明中使用 throws 关键字指定了可能抛出的 FileNotFoundException 异常。
在 main 方法中调用 readFile(file.txt) 时如果文件不存在将会抛出 FileNotFoundException 异常。由于我们使用了 throws 来声明可能抛出的异常因此需要通过在 main 方法中使用 catch 块来捕获并处理该异常。
通过使用 throws我们可以将异常的处理责任交给调用者或上层代码从而使代码更加模块化和灵活。调用者可以选择捕获并处理异常或继续向上层代码传递异常直到有相应的异常处理机制为止。
throw
throw 关键字用于手动抛出一个异常。它可以用于任何地方包括方法、构造函数、代码块和其他异常处理机制中。通过使用 throw 关键字可以在程序中指示错误或异常情况并将控制权交给上层代码或异常处理机制来处理。
抛出异常的一般语法如下
throw throwableObject;其中throwableObject 是要抛出的异常对象可以是 Java 内置的异常类如 RuntimeException、IOException 等或自定义的异常类的实例。
以下是一个使用 throw 抛出异常的例子
public class AgeValidation {public static void main(String[] args) {try {int age -5;validateAge(age);} catch (IllegalArgumentException e) {System.out.println(年龄无效);e.printStackTrace();}}public static void validateAge(int age) {if (age 0) {throw new IllegalArgumentException(年龄不能为负数);}System.out.println(年龄有效);}
}在上述代码中我们有一个 validateAge 方法它接收一个年龄作为参数并通过判断年龄是否为负数来验证年龄的有效性。如果年龄为负数则使用 throw 关键字手动抛出一个 IllegalArgumentException 异常并提供错误消息 “年龄不能为负数”。
在 main 方法中调用 validateAge(-5) 时传入了一个负数作为年龄触发了异常的抛出。然后在 catch 块中捕获并处理该异常。
通过使用 throw我们可以在需要的时候手动抛出异常以便在程序中指示错误或异常情况并将异常控制权交给上层代码或异常处理机制。这有助于提高程序的可读性和可维护性并实现更精确的异常处理。
throw与throws的区别
throw 和 throws 是在异常处理中使用的关键字它们有以下差别 功能不同 throw 用于主动抛出异常。它可以在任何地方使用用于手动抛出一个异常对象。throws 用于在方法声明中指定该方法可能抛出的异常类型。它用于向调用者或上层代码声明当前方法可能会抛出的异常以便调用者能够适当地处理异常。 使用位置不同 throw 关键字可以用于方法、构造函数、代码块或其他异常处理机制内部的任何位置。throws 关键字只能在方法或构造函数的声明部分使用用于指定该方法可能抛出的异常。 异常处理责任不同 使用 throw 抛出异常后控制权会立即转移到调用栈中的适当的异常处理机制如 try-catch 块。使用 throws 声明异常后方法仍然可以继续执行并将异常的处理责任交给调用该方法的代码。
综上所述throw 用于手动抛出异常而 throws 用于在方法声明中指定可能抛出的异常类型。throw 直接触发异常并将控制权转移给异常处理机制而 throws 声明异常后方法仍然会执行将异常抛给调用者处理。
自定义异常
在Java中可以通过创建自定义异常类来实现用户定义的异常。自定义异常类可以根据特定的业务需求或异常情况提供更具体、更清晰的异常信息并允许开发者以自定义的方式处理异常。
创建自定义异常类的步骤如下 创建一个继承自 Exception 或其子类的类并命名为你想要的异常类名。 在自定义异常类中可以添加自定义的构造方法和其他方法用于初始化异常对象和提供额外的异常信息。 可以选择重写父类的方法或添加自定义的方法来满足特定的需求。例如可以添加方法来获取更详细的异常信息。
下面是一个简单的自定义异常类的例子
public class InvalidAgeException extends Exception {private int age;public InvalidAgeException(int age) {super(年龄不合法);this.age age;}public int getAge() {return age;}
}在上述代码中我们创建了一个自定义的异常类 InvalidAgeException它继承自 Exception 类。该异常类具有一个带有参数的构造方法用于初始化异常对象并提供年龄信息。我们还添加了一个 getAge 方法用于获取年龄信息。
使用自定义异常类时可以在代码中以相同的方式处理它们就像处理内置的异常类一样。例如可以使用 try-catch 块来捕获和处理自定义异常。
以下是一个使用自定义异常的示例
public class AgeValidation {public static void main(String[] args) {try {int age -5;validateAge(age);} catch (InvalidAgeException e) {System.out.println(年龄无效年龄为 e.getAge());e.printStackTrace();}}public static void validateAge(int age) throws InvalidAgeException {if (age 0) {throw new InvalidAgeException(age);}System.out.println(年龄有效);}
}在上述代码中我们使用自定义异常类 InvalidAgeException 来实现对年龄的验证。当年龄为负数时我们使用 throw 关键字抛出 InvalidAgeException 异常并将年龄作为参数传递给异常构造方法。在 main 方法中通过 try-catch 块捕获并处理该异常。
自定义异常类的使用可以提供更具体和详细的异常信息使异常处理更精确和可控。它可以让开发者根据特定的业务需求创建和处理异常从而提高程序的可读性和可维护性。
异常的优点
1. 异常处理机制异常提供了一种结构化的错误处理机制使开发者能够更容易地检测、捕获和处理错误。通过合理使用异常处理可以提高代码的可维护性和可读性。
2. 分离正常流程和异常处理逻辑异常机制将正常的业务逻辑与异常处理逻辑分离开来。这样在编写代码时可以将主要注意力放在正常情况下的逻辑流程上而将异常情况作为特殊情况进行处理。
3. 提供错误信息和堆栈追踪异常对象中包含有关错误的详细信息例如异常类型、错误消息和堆栈追踪。这些信息能够帮助开发者快速定位和解决问题缩短调试时间。
4. 异常传播和处理异常机制允许异常在调用栈中传播直到被捕获并处理。这意味着一个方法中的异常可以由该方法的调用者捕获和处理使得异常的处理可以在不同的层次上进行。
5. 提高代码可靠性和稳定性通过捕获和处理异常可以防止程序因遇到错误而崩溃或产生不可预测的行为。合理处理异常可以增强代码的健壮性使程序更可靠和稳定。
6. 资源释放异常处理机制还可以确保在异常情况下正确释放和关闭系统资源避免资源泄露和其他问题。
总结 本文我们为大家详细的介绍了关于异常的知识点异常的使用可以让我们提高对代码的掌控能力异常就像手术刀一样可以精准的切割我们的bug部分使我们快速的对代码进行修改异常是一种强大的错误处理工具可以帮助开发者优雅地处理异常情况提高代码的可靠性和可维护性。合理地使用异常处理机制可以改善程序的质量提高开发效率。
如果我的内容对你有帮助请点赞评论收藏。创作不易大家的支持就是我坚持下去的动力