当前位置: 首页 > news >正文

学习日志03 java

最近有点懈怠了,多多实践,多敲代码,多多专注!

1 ArithmeticException

ArithmeticException 是 Java 中的一个异常类,它继承自 RuntimeException,用于表示在算术运算中出现的错误。这个异常通常在以下情况下抛出:

  1. 整数除以零:当你尝试用一个整数(如 intlong 等)除以零时,会抛出 ArithmeticException

    java

    int result = 10 / 0; // 这行代码会抛出 ArithmeticException
    
  2. 模运算(取余)中除数为零:同样,整数的模运算中如果除数是零,也会抛出此异常。

    java

    int remainder = 10 % 0; // 这行代码也会抛出 ArithmeticException
    
  3. 其他情况:在极少数情况下,某些库或自定义代码可能会显式抛出这个异常,但最常见的场景还是整数除零。

注意事项

  • 浮点数除零:对于浮点数(如 float 和 double),除以零不会抛出异常,而是返回无穷大(Infinity)或 NaN(Not a Number)。

    java

    double result = 10.0 / 0.0; // 返回 Infinity
    double invalid = 0.0 / 0.0; // 返回 NaN
    
  • 如何避免:在进行除法或模运算前,应先检查除数是否为零。

    java

    int divisor = 0;
    if (divisor != 0) {int result = 10 / divisor;
    } else {System.out.println("除数不能为零");
    }
    
  • 异常处理:如果你无法在代码中预先检查除数是否为零,可以使用 try-catch 块捕获异常。

    java

    try {int result = 10 / divisor;
    } catch (ArithmeticException e) {System.out.println("发生算术异常: " + e.getMessage());
    }
    

总结

ArithmeticException 主要用于处理整数运算中的除零错误,是一个运行时异常(不需要显式捕获)。在编写代码时,建议通过条件判断避免除零操作,或使用异常处理机制增强程序的健壮性。

2 java里面的异常体系结构

写捕获异常的时候要从小到大写,要不然会被覆盖。

throw new RuntimeException(e); 的含义

package Exception;public class Test2 {public static void main(String[] args) {int a =1;int b =0;try {System.out.println(a/b);} catch (Exception e) {throw new RuntimeException(e);} finally {}}
}

throw new RuntimeException(e); 的含义是把捕获到的异常 e 封装成一个新的运行时异常 RuntimeException,然后再次抛出。

---------------------------------------------------------------------------------------------------------------------------------Q:new出来的这个异常对象是我随便想叫什么名字的吗?(・∀・(・∀・(・∀・*)

A:在 Java 里,通过new关键字创建异常对象时,异常变量的命名规则和普通变量是一样的。也就是说,你能按照自己的想法来命名,不过为了保证代码的可读性,一般会使用能体现异常类型或者含义的名称。

=========================================================================

这里的 e 是原始异常对象,作为参数传入,它会成为新异常的原因(cause)。这种做法被称作异常包装或者异常链

为什么要进行异常包装?

  1. 隐藏底层实现细节:假设你设计的是一个数据库工具类,当出现 SQLException 时,你不想让上层调用者直接处理这个特定的数据库异常,于是将其包装成更通用的 RuntimeException
  2. 异常类型转换:受检查异常(像 IOException)无法直接抛出,这时可以把它包装成运行时异常,从而避免进行 throws 声明。
  3. 添加更多上下文信息:你可以创建自定义的异常类,然后把原始异常包装在其中,为异常处理提供更多的信息。

异常包装的示例

下面是一个简单的工具类示例,展示了如何使用异常包装:

public class FileUtils {public static String readFile(String path) {try {return Files.readString(Path.of(path));} catch (IOException e) {// 将受检查异常包装成运行时异常throw new RuntimeException("读取文件失败: " + path, e);}}
}

处理包装后的异常

在调用栈的上层,你可以捕获这个包装后的异常,并且通过 getCause() 方法获取原始异常:

java

try {FileUtils.readFile("nonexistent.txt");
} catch (RuntimeException e) {System.err.println("发生错误: " + e.getMessage());// 获取原始异常Throwable originalCause = e.getCause();if (originalCause instanceof IOException) {System.err.println("原始错误: 文件不存在");}
}

你提供的代码存在的问题

在你的代码里,捕获到 ArithmeticException 后又把它包装成 RuntimeException 抛出,这是多此一举的。因为 ArithmeticException 本身就是运行时异常,完全可以直接抛出。更合适的处理方式应该是:

java

try {System.out.println(a/b);
} catch (ArithmeticException e) {System.err.println("除数不能为零!");// 或者记录日志// logger.error("除数为零", e);
}

总结来说,异常包装是一种很有用的技巧,但要根据具体场景合理运用。在你的代码中,这样的包装并没有实际价值。

4 有关new出来的异常对象的命名

变量命名规范

下面是一些常见的命名方式:

java

try {// 执行可能会抛出异常的代码
} catch (ExceptionType e) { // 通常使用单个字母,像e、exthrow new RuntimeException("错误信息", e);
}// 或者使用更具描述性的名称
try {// ...
} catch (FileNotFoundException fileNotFoundEx) {throw new RuntimeException("文件未找到", fileNotFoundEx);
}// 也可以使用全小写加下划线的形式(不过这种方式不太常用)
try {// ...
} catch (SQLException sql_exception) {// ...
}

命名建议!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  1. 保持简洁:使用eex或者简单的描述,例如fileError
  2. 类型清晰:命名要能体现异常的类型,比如networkExceptionparseError
  3. 避免重复:不要使用和已有变量相同的名称。

异常类名与变量名的区别

需要注意的是,异常类名(像RuntimeException)是固定的,必须使用已有的类或者自定义类,而异常对象的变量名(如e)则可以自由命名。

java

// 正确:使用已有的异常类,变量名可自由选择
catch (Exception e) {throw new MyCustomException("自定义错误", e); // MyCustomException 是自定义的异常类
}// 错误:不能随意编造异常类名
catch (Exception e) {throw new MyRandomException(); // 编译会报错,因为 MyRandomException 类不存在
}

总结

你可以自由命名异常对象的变量,但异常类名必须是已存在的类。建议采用简洁且能描述异常性质的命名方式,比如:

java

try {int result = divide(1, 0);
} catch (ArithmeticException divisionError) {throw new RuntimeException("除法运算失败", divisionError);
}

5 介绍throw和throws 

throw 和 throws 是 Java 中用于处理异常的两个关键字,它们的主要区别在于位置用途

一、基本用法

1. throw(主动抛出异常)
  • 位置:用在方法内部,用于主动抛出一个异常对象
  • 语法throw new ExceptionType("错误信息");
  • 示例

    java

    public void divide(int a, int b) {if (b == 0) {throw new ArithmeticException("除数不能为零"); // 主动抛出异常}System.out.println(a / b);
    }
    
2. throws(声明异常)
  • 位置:放在方法签名后面,用于声明该方法可能会抛出的异常
  • 语法returnType methodName(params) throws ExceptionType1, ExceptionType2... { ... }
  • 示例

    java

    public void readFile(String path) throws FileNotFoundException {File file = new File(path);if (!file.exists()) {throw new FileNotFoundException("文件不存在"); // 抛出异常}// ...
    }
    

二、核心区别

---------------------------------------------------------------------------------------------------------------------------------

对比项throwthrows
位置方法内部方法签名后面
作用主动抛出一个异常对象声明方法可能抛出的异常类型
语法throw new Exception(...);void method() throws Exception {...}
异常类型只能抛出一个具体的异常对象可以声明多个异常类型,用逗号分隔
处理要求必须被捕获(try-catch)或继续向上抛出调用者必须处理受检查异常(Checked Exception)

三、联系与配合

  1. 受检查异常必须配合 throws

    • 如果方法内部抛出受检查异常(如 IOException),则必须在方法签名中用 throws 声明。

    java

    public void writeFile() throws IOException { // 必须声明 throwsFileWriter writer = new FileWriter("test.txt");// ...
    }
    
  2. 异常传递链

    • throw 抛出的异常可以通过 throws 层层向上传递,直到被 try-catch 捕获。

    java

    public void methodA() throws IOException {throw new IOException("文件错误"); // 抛出异常
    }public void methodB() throws IOException {methodA(); // 未处理异常,继续向上抛
    }public void methodC() {try {methodB(); // 最终捕获异常} catch (IOException e) {e.printStackTrace();}
    }
    

四、常见误区

  1. throw 后不能有后续代码

    java

    public void test() {throw new RuntimeException();System.out.println("永远执行不到"); // 编译错误!
    }
    
  2. throws 不负责处理异常

    • throws 只是声明异常,真正的处理(try-catch)要在调用链的上层完成。
  3. 运行时异常(RuntimeException)不强制要求 throws

    java

    public void divide(int a, int b) {if (b == 0) {throw new ArithmeticException(); // 无需声明 throws}
    }
    

五、总结

  • throw:用于 “制造” 异常,是异常的源头。
  • throws:用于 “传递” 异常,提醒调用者处理潜在的异常。
  • 配合使用:当方法内部 throw 受检查异常时,必须用 throws 声明;调用者可以继续 throws 或用 try-catch 捕获。

6 自定义异常在实际应用中的经验总结

1 处理运行时异常时,采用逻辑去合理规避同时辅助 try-catch 处理

2 在多重 catch 块后面,可以加一个 catch (Exception)(放一个最大的异常哈) 来处理可能会被遗漏的异常

3 对于不确定的代码,也可以加上 try-catch,处理潜在的异常(IDE一般会报错,这个时候呢alt + enter 可以自动提示

4 尽量去处理异常增加一些处理异常的代码块!!切忌只是简单地调用 printStackTrace () 去打印输出(这个是默认的处理哈

5具体如何处理异常,要根据不同的业务需求和异常类型去决定(这个多多实践吧,,,)

6 尽量添加 finally 语句块去释放占用的资源(IO Scanner异常之类的哈,涉及到资源的释放)

http://www.xdnf.cn/news/398161.html

相关文章:

  • 【Java继承】——面向对象编程的基石
  • ngx_http_limit_conn_module精准连接控制
  • C#里WPF使用触发器实现鼠标点击响应
  • 谷歌Gemini生图升级:与GPT-4o的对决,谁更胜一筹?
  • 克隆虚拟机组成集群
  • Python爬虫第20节-使用 Selenium 爬取小米商城空调商品
  • Electron学习大纲
  • 从零开始的python学习(七)P89+P90+P91+P92+P93+P94
  • 关于高并发GIS数据处理的一点经验分享
  • flutter 的 json序列化和反序列化
  • 南京邮电大学金工实习答案
  • 全模态具身智能:从 VLM 到 MLLM
  • Multisim14使用教程详尽版--(2025最新版)
  • 【网络原理】数据链路层
  • 场馆订 场馆预订平台 数据库设计
  • 如何构建通用深度反思(deep-research)能力的Agent?
  • 5.串口的输入输出
  • redis数据结构-04 (HINCRBY、HDEL、HKEYS、HVALS)
  • 牛客周赛 Round 92-题解
  • Java并发编程实战
  • 简单的强化学习举例
  • 笔试阶段性心得总结
  • 模块化编程
  • ACM模式手动构建二叉树
  • 算法导论第9章思考题
  • 深入理解深度循环神经网络(Deep RNN)
  • Beta分布--贝叶斯建模概率或比例常用分布
  • eNsp的使用
  • 数据结构【二叉树的遍历实现】
  • 免费公共DNS服务器推荐