包装类
包装类
包装类是一种将基本数据类型封装为对象的类。在Java中,每种基本数据类型都有对应的包装类,用于在需要对象的上下文中使用基本数据类型。
基本类型和对应包装类
byte对应Byteshort对应Shortint对应Integerlong对应Longfloat对应Floatdouble对应Doublechar对应Characterboolean对应Boolean
示例代码
// 使用包装类创建对象
Integer num1 = new Integer(10);
Double num2 = new Double(3.14);
// 自动装箱(Autoboxing)
Integer num3 = 20;
Double num4 = 6.28;
// 自动拆箱(Unboxing)
int value1 = num1.intValue();
double value2 = num2.doubleValue();
// 包装类与基本类型的比较
Integer num5 = 30;
int value3 = num5; // 自动拆箱
if (value3 == num5) {
System.out.println("数值相等");
}
拆箱和装箱
拆箱(Unboxing)和装箱(Autoboxing)是Java中基本数据类型和对应包装类之间的自动转换过程。
装箱(Autoboxing)
装箱是将基本数据类型转换为对应的包装类对象的过程。在需要使用包装类对象的地方,可以直接将基本数据类型赋值给包装类对象,编译器会自动进行转换。
示例代码:
Integer num1 = 10; // 自动装箱
Double num2 = 3.14; // 自动装箱
拆箱(Unboxing)
拆箱是将包装类对象转换为对应的基本数据类型的过程。在需要使用基本数据类型的地方,可以直接将包装类对象赋值给基本数据类型变量,编译器会自动进行转换。
示例代码:
Integer num3 = new Integer(20);
int value1 = num3; // 自动拆箱
Double num4 = new Double(6.28);
double value2 = num4; // 自动拆箱
通过装箱和拆箱,可以方便地在基本数据类型和包装类对象之间进行转换,使代码更加简洁和易读。
异常
在Java中,异常是指程序在运行过程中发生的意外情况,例如除零、空指针引用等。异常处理是Java程序设计中的重要部分,可以保护程序免受错误的影响,并提供更好的用户体验。
异常类层次结构
Java中的异常是以类的形式存在的,它们都是Throwable类的子类。异常类主要分为两种:Error和Exception。
Exception的分类
Exception类是所有异常的父类,它又分为两种:受检异常(Checked Exception)和运行时异常(Runtime Exception)。
受检异常(Checked Exception)
受检异常是指在编译时必须进行处理的异常,即在代码中必须显式地进行捕获或声明抛出。受检异常通常是程序运行时可能出现的外部因素导致的异常,如文件不存在、网络连接中断等。
示例:IOException、SQLException等。
运行时异常(Runtime Exception)
运行时异常是指在运行时可能出现的异常,不需要在代码中显式地进行捕获或声明抛出。运行时异常通常是由程序逻辑错误导致的异常,如空指针引用、数组越界等。
示例:NullPointerException、ArrayIndexOutOfBoundsException等。
自定义异常
除了Java提供的异常类外,程序员还可以根据需要自定义异常类。自定义异常类通常继承自Exception或其子类,用于描述特定的异常情况,并可以根据业务需求添加额外的信息或处理逻辑。
通过对Exception类的分类,程序员可以更好地处理不同类型的异常情况,提高程序的健壮性和可靠性。
常见的异常类包括:
NullPointerException:空指针异常ArithmeticException:算术异常,如除零ArrayIndexOutOfBoundsException:数组下标越界异常FileNotFoundException:文件未找到异常IOException:输入输出异常RuntimeException:运行时异常的基类
异常处理
在Java中,异常处理主要通过try-catch-finally语句块来实现。try块用于包含可能抛出异常的代码,catch块用于捕获并处理异常,finally块用于执行无论是否发生异常都需要执行的代码。
示例代码:
try {
// 可能抛出异常的代码
int result = 10 / 0; // 除零异常
} catch (ArithmeticException e) {
// 捕获并处理异常
System.out.println("除零异常:" + e.getMessage());
} finally {
// 无论是否发生异常都会执行的代码
System.out.println("异常处理结束");
}
抛出异常
除了捕获并处理异常,Java中还可以使用throw关键字手动抛出异常。通过throw关键字,可以在程序中根据特定条件主动抛出异常,以便在合适的地方进行处理。
示例代码:
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
System.out.println("年龄为:" + age);
}
通过异常处理,可以使程序更加健壮,提高程序的可靠性和稳定性。
异常处理详解
在Java中,异常处理是通过一系列关键字和语句来实现的,包括try、catch、finally、throws和throw。下面将详细解释这些关键字的用法,并给出示例代码。
try-catch-finally
try:try块用于包含可能抛出异常的代码块。在try块中的代码会被监视,一旦发生异常,程序会跳转到对应的catch块进行处理。catch:catch块用于捕获并处理异常。在catch块中可以指定捕获的异常类型,并编写处理异常的代码逻辑。finally:finally块用于包含无论是否发生异常都需要执行的代码。通常用于释放资源或执行清理操作。即使遇到return 也会执行finally,除非虚拟机关闭。
示例代码:
try {
int result = 10 / 0; // 除零异常
} catch (ArithmeticException e) {
System.out.println("捕获到除零异常:" + e.getMessage());
} finally {
System.out.println("无论是否发生异常,都会执行这里的代码");
}
throws
throws:throws关键字用于在方法声明中指定可能抛出的异常类型。当方法中可能抛出异常时,可以使用throws关键字将异常抛给调用者处理。
示例代码:
public void readFile() throws IOException {
// 读取文件的代码
}
throw
throw:throw关键字用于手动抛出异常。通过throw关键字,可以在程序中根据特定条件主动抛出异常,以便在合适的地方进行处理。
示例代码:
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
System.out.println("年龄为:" + age);
}
通过try-catch-finally和throws关键字,可以处理和抛出异常;而通过throw关键字,可以手动抛出异常,从而更好地控制程序的异常处理流程。
在Java中,Exception类及其子类提供了多种方法来获取异常的详细信息。以下是一些常用的方法及其解释,配合代码示例:
1. getMessage()
描述:返回一个描述异常的详细信息的字符串。
示例代码:
try {
int result = 10 / 0; // 除零异常
} catch (ArithmeticException e) {
System.out.println("异常信息: " + e.getMessage());
}
2. printStackTrace()
描述:打印异常的详细堆栈跟踪信息,包括异常的类型、消息和发生异常的代码行。
示例代码:
try {
String str = null;
str.length(); // 空指针异常
} catch (NullPointerException e) {
e.printStackTrace(); // 打印堆栈跟踪
}
3. toString()
描述:返回异常的类名和详细信息的字符串,通常包含异常的类型和消息。
示例代码:
try {
int[] arr = new int[2];
int value = arr[5]; // 数组下标越界异常
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("异常描述: " + e.toString());
}
4. getCause()
描述:返回导致当前异常的原因(即另一个异常),如果没有原因则返回
null。示例代码:
try {
throw new IllegalArgumentException("非法参数", new NullPointerException("参数为null"));
} catch (IllegalArgumentException e) {
System.out.println("异常原因: " + e.getCause());
}
5. getStackTrace()
描述:返回一个
StackTraceElement数组,表示异常发生时的堆栈跟踪信息。示例代码:
try {
int result = 10 / 0; // 除零异常
} catch (ArithmeticException e) {
StackTraceElement[] stackTrace = e.getStackTrace();
for (StackTraceElement element : stackTrace) {
System.out.println("类名: " + element.getClassName() + ", 方法名: " + element.getMethodName() + ", 行号: " + element.getLineNumber());
}
}
6. fillInStackTrace()
描述:用当前线程的堆栈跟踪信息填充异常的堆栈跟踪信息,通常用于在捕获异常后重新抛出异常。
示例代码:
try {
throw new Exception("自定义异常");
} catch (Exception e) {
e.fillInStackTrace(); // 填充堆栈跟踪
throw e; // 重新抛出异常
}
多个 catch 块
在 Java 的异常处理中,一个 try 块可以包含多个 catch 块,用于捕获不同类型的异常并分别处理。当 try 块中的代码抛出异常时,程序会按照 catch 块的顺序逐个匹配异常类型,执行匹配到的第一个 catch 块,并且只会执行其中的代码块。
多个 catch 块的语法
try {
// 可能抛出异常的代码
} catch (ExceptionType1 e1) {
// 处理 ExceptionType1 类型的异常
} catch (ExceptionType2 e2) {
// 处理 ExceptionType2 类型的异常
} catch (Exception e) {
// 处理其他类型的异常
} finally {
// 无论是否发生异常都会执行的代码
}
多个 catch 块的执行流程
当 try 块中的代码抛出异常时,程序会按照 catch 块的顺序逐个匹配异常类型。
如果异常类型与某个 catch 块匹配,则执行该 catch 块中的代码,并结束异常处理流程。
如果异常类型与多个 catch 块匹配,则只会执行第一个匹配的 catch 块。
如果异常类型没有匹配任何 catch 块,则异常会被抛给上层调用者或者由 JVM 处理。
捕获先写范围小的,在写范围大的。
示例代码
try {
int[] numbers = {1, 2, 3};
System.out.println(numbers[3]); // 数组越界异常
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("捕获到数组越界异常:" + e.getMessage());
} catch (NullPointerException e) {
System.out.println("捕获到空指针异常:" + e.getMessage());
} catch (Exception e) {
System.out.println("捕获到其他异常:" + e.getMessage());
} finally {
System.out.println("无论是否发生异常,都会执行这里的代码");
}
在上面的示例中,如果数组越界异常发生,则会匹配第一个 catch 块并执行相应的处理代码;如果是空指针异常,则会匹配第二个 catch 块;如果是其他类型的异常,则会匹配最后一个 catch 块。无论哪种异常发生,最终都会执行 finally 块中的代码。
通过多个 catch 块,可以根据不同类型的异常进行精细化的处理,提高程序的健壮性和可靠性。
自定义异常
在Java中,除了使用Java提供的异常类外,程序员还可以根据需要自定义异常类。自定义异常类通常继承自Exception或其子类,用于描述特定的异常情况,并可以根据业务需求添加额外的信息或处理逻辑。
自定义异常的步骤
创建一个继承自Exception或其子类以及超类throwable的自定义异常类。
在自定义异常类中添加构造方法,用于初始化异常信息。
可选:添加自定义方法或属性,以满足特定的异常处理需求。
示例代码
// 自定义异常类
class CustomException extends Exception {
private int errorCode;
// 构造方法,初始化异常信息
public CustomException(String message, int errorCode) {
super(message);
this.errorCode = errorCode;
}
// 获取错误码的方法
public int getErrorCode() {
return errorCode;
}
}
// 使用自定义异常
public class CustomExceptionExample {
public static void main(String[] args) {
try {
validateAge(-1);
} catch (CustomException e) {
System.out.println("捕获到自定义异常:" + e.getMessage());
System.out.println("错误码:" + e.getErrorCode());
}
}
// 自定义方法,抛出自定义异常
public static void validateAge(int age) throws CustomException {
if (age < 0) {
throw new CustomException("年龄不能为负数", 1001);
}
System.out.println("年龄为:" + age);
}
}
在上面的示例中,我们定义了一个自定义异常类CustomException,它继承自Exception类,并添加了一个errorCode属性用于表示错误码。在CustomException类的构造方法中,我们初始化异常信息并设置错误码。然后在CustomExceptionExample类中,我们使用自定义异常类来处理年龄验证的逻辑。当年龄为负数时,会抛出自定义异常,并在捕获异常后输出异常信息和错误码。
通过自定义异常类,我们可以更好地描述和处理特定的异常情况,使程序的异常处理更加灵活和具有针对性。
Comments