1. 异常捕捉的陷阱
异常处理机制是java语言的特色之一,尤其是java语言的Checked异常,更是体现了java语言的严谨性:没有完善错误处理的代码根本不会被执行。对于Checked异常,java程序要么声明抛出,要么使用try……catch进行捕获。
1.1 正确关闭资源的方式
在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接,网络连接,磁盘文件等,打开这些物理资源之后必须显示关闭,否则将会导致资源泄漏。因为垃圾回收机制属于java内存管理的一部分,它只是负责会受堆内存中分配出来的内存,至于程序中打开的物理资源,垃圾回收机制是无能为力的。
为了正常关闭程序中打开的物理资源,应该使用finally块来保证回收。比如下面三种关闭资源的方式,哪种更好些?
public static void main(String args[]) throws Exception { Student student_new = new Student("liyafang"); Student student_recover = null; ObjectOutputStream oos = null; ObjectInputStream ois = null; try { oos = new ObjectOutputStream(new FileOutputStream("liyafang.txt")); ois = new ObjectInputStream(new FileInputStream("liyafang.txt")); oos.writeObject(student_new); oos.flush(); student_recover = (Student) ois.readObject(); System.out.println(student_recover.equals(student_new)); System.out.println(student_recover == student_new); } finally { //1.第一种关闭资源的方式(不够安全):程序刚开始指定oos = null;ois = null;完全有可能在程序运行过程中初始化oos之前就引发了异常,那么oos,ois还没有来得及初始化,因此oos,ois根本无需关闭。 oos.close(); ois.close(); //2.第二种关闭资源的方式(还是不够安全):假如程序开始已经正常初始化了oos,ois两个IO流,在关闭oos是出现了异常,那么程序将在关闭oos时非正常退出,这样就导致ois得不到关闭,从而导致资源泄漏。为了保证关闭各资源时出现的异常不会相互影响,应该在关闭每个资源时分开使用try catch块来保证关闭操作不会导致程序非正常退出。 if(oos != null){ oos.close(); } if(ois != null){ ois.close(); } //3.第三种关闭资源的方式(比较安全):主要保证一下几点: //(1)使用finally块来关闭物理资源,保证关闭操作始终会被执行; //(2)关闭每个资源之前首先保证引用该资源的引用变量不为null; //(3)为每个物理资源使用单独的trycatch块关闭资源,保证关闭资源时引发的异常不会影响其他资源的关闭。 if(oos != null){ try{ oos.close(); }catch (Exception ex){ ex.printStackTrace(); } } if(ois != null){ try{ ois.close(); }catch (Exception ex){ ex.printStackTrace(); } } } }1.2 finally块的陷阱
当程序在finally之前使用System.exit(0),finally将不执行。调用System.exit(0)将使JVM退出,只要JVM不退出,finally就一定会得到执行。
在java程序执行try块、catch块时遇到了return语句,return语句会导致该方法立即结束。系统执行完return语句之后,并不会立即结束该方法,而是去寻找该异常处理流程中是否包含Finally块,如果没有Finally块,方法终止,返回相应的返回值。如果有Finally块,系统立即开始执行Finally块,只有当Finally执行完成后,系统才会再次跳回来根据return语句结束方法。如果Finally块使用了return语句来导致方法的结束,则finally块已经结束了方法,系统不会跳回去执行trycatch里的任何代码。
public int test(){ int count = 1; try{ return ++count; }finally{ return ++count; } } //以上代码最终返回值是:3 public int test(){ int count = 1; try{ return ++count; }finally{ return count++; } } //以上代码最终返回值是:2throw语句的执行和return语句比较类似。当程序执行trycatch块遇到throw语句时,throw语句会导致该方法立即结束,系统执行throw语句时并不会立即抛出异常,而是去寻找该异常处理流程中是否包含finally块。如果没有finally块,程序立即抛出异常。如果有finally块,系统立即执行finally块,只有当finally块执行完成之后,系统才会再次跳出来抛出异常。如果finally块里使用return语句来结束方法,系统将不会跳回去执行try块,catch块去抛出异常。
例如1:
int count = 1; try{ throw new RuntimeException("异常1"); }finally{ return count++; } //执行结果:返回值是1,同时不会抛出任何异常。例如2:
int count = 1; try{ throw new RuntimeException("异常1"); }finally{ throw new RuntimeException("异常2"); } //执行结果:Exception in thread "main" java.lang.RuntimeException: 异常21.3 catch块的用法
1.3.1 catch的顺序
对于java的异常捕获来说,每个try块至少需要一个catch块或一个finally块,绝不能只有单独一个孤零零try块。通常情况下,如果try块被执行一次,则try块后只有一个catch块会被执行,绝不可能有多个catch块被执行。除非在循环中使用了continue开始下一次循环,下一次循环又重新运行了try块,才可能导致多个catch块被执行。由于异常处理机制中排在前面的catch(XxxException ex)块总是会优先获得执行的机会,因此java对try块后的多个catch块的排列顺序是有要求的。
因为java的异常有非常严格的继承体系,许多异常类之间有严格的父子关系,比如程序FileNotFoundException异常就是IOException的子类。捕获父类异常的catch块都应该排在捕捉子类异常的catch块之后【先处理小异常(子类异常),在处理大异常(父类异常)】,否则将出现编译错误。
例如以下两个catch语句不能颠倒顺序:
FileInputStream fis = null; try{ fis = new FileInputStream("a.bin"); fis.read(); }catch(FileNotFoundException ex){ ex.printStackTrace(); }catch(IOException e){ e.printStackTrace(); }1.3.2不要用catch代替流程控制
如下边这个例子:
String[] students = {"liyafang","zhoushilong","luorongbo"}; int i = 0; while(true){ try{ System.out.println(students[i++]); }catch(IndexOutOfBoundsException ex){ break; } }这种遍历数组的方式不仅难以阅读,而且运行速度还非常慢。
千万不要使用异常来进行流程控制。异常机制不是为流程控制而准备的,异常机制知识为程序的意外情况准备的,因此程序只应该为异常情况使用异常机制。所以,不要使用这种“别出心裁”的方法来遍历数组。
1.3.3只能catch可能抛出的异常
/*public static void test1(){ try{ System.out.println("something"); }catch(IOException e){ e.printStackTrace(); } } public static void test2(){ try{ System.out.println("something"); }catch(ClassNotFoundException e){ e.printStackTrace(); } }*/以上代码java编译器是不允许的。
根据java语言规范,如果一个catch子句试图捕获一个类型为XxxException的Checked异常时,那么它对应的try子句必须可能抛出XxxException或其子类的异常,否则编译器将提示该程序具有编译错误—但在所有的Checked异常中,Exception是一个异类,无论try块是怎样的代码,catch(Exception e)总是正确的。
RuntimeException 类及其子类的实例被称为Runtime异常,不是RuntimeException类及其子类的异常实例则被称为Checked异常,只要愿意,程序员总可以使用catch(XxxException ex)来捕获运行时异常。
总之,程序使用catch捕捉异常时,其实并不能随心所欲地捕捉所有异常。程序可以在任意想捕捉的地方捕捉RuntimeException异常,Exception,但对于其他的Checked异常,只有当try块可能抛出该异常时(try块中调用的某个方法声明抛出了该Checked异常),catch块才捕捉该Checked异常。
1.3.4实际的修复
如果程序知道如何修复指定异常,应该在catch块内尽量修复该异常,当该异常情况被修复后可以再次调用该方法;如果程序不知道如何修复该异常,也没有进行任何修复,千万不要再次调用可能导致该异常的方法。
无论如何不要在finally块中递归调用可能引起异常的方法,因为这将导致该方法的异常不能被正常抛出,甚至StackOverflowError错误也不能中止程序,只能采用强行结束java.exe进程的方法来中止程序的运行。
1.4 继承得到的异常
Java语言规定:子类重写父类的方法时,不能声明抛出比父类方法类型更多,范围更大的异常。也就是说,子类重写父类方法时,子类方法只能声明抛出父类方法所声明抛出的异常的子类。
例如:
public interface Type1 { void test() throws ClassNotFoundException; } public interface Type2 { void test() throws NoSuchMethodException; } class Test implements Type1, Type2 { @Override public void test() { } }上面代码的异常处理是正确的。
Test实现了Type1接口,实现Type1接口里的test()方法时可以声明抛出ClassNotFoundException异常或该异常的子类,或者不声明抛出;Test类实现了Type2接口,实现了Type2接口里的test()方法时可以声明抛出NoSuchMethodException异常或该异常的子类,或者不声明抛出。由于Test类同时实现了Type1,Type2两个接口,因此需要同时实现两个接口中的test()方法。只能是上面两种声明抛出的交集,不能声明抛出任何异常。
相关推荐
iOS逆向实战:绕过SSL Pinning抓取ChatGPT设备令牌
在移动应用安全与网络协议分析领域,中间人攻击是一种核心的流量拦截与分析技术。其原理是在客户端与服务器之间插入一个代理节点,通过伪造数字证书来解密和窥探HTTPS加密流量。这项技术的工程价值在于,它使开发者能够调试API、分析通信协议以及实现自动化集成。然而,许多高安全要求的应用(如金融、社交类App)会采用SSL Pinning(证书绑定)技术来抵御此类攻击,这为逆向工程带来了挑战。本文聚焦于一个具体的应用场景:如何针对启用了SSL Pinning的ChatGPT iOS客户端,通过特定的工具链(如Trol
JasperReport报表导出常见问题(内存泄漏)
JasperReport报表导出常见问题 (内存泄漏)
ZYNQ-7035+HMCAD1511高速数据采集系统设计
高速数据采集是电子测量、雷达信号处理与通信基带验证的核心技术基础,其性能瓶颈常集中于采样率、通道同步性与实时处理能力。基于ADC采样原理与SoC异构架构,高带宽、低抖动时钟链路与FPGA+ARM协同处理成为突破关键。ZYNQ-7035凭借275K逻辑单元与千级DSP资源,显著提升LVDS数据流吞吐与片上滤波/触发等实时算法部署能力;HMCAD1511则以1GSPS四通道同步采样和8位分辨率,满足示波器级动态范围需求。该组合广泛应用于嵌入式信号采集平台开发、教学实验系统构建及国产化仪器原型验证。
Avoid empty catch blocks
http://www.javapractices.com/topic/TopicAction.do?Id=16 Most contend that it's usually a very bad idea to have an empty catch block. When the exception occurs, nothing happens, and the program fai
钣金件设计规范
为保证折弯 强度,钣金折弯钣金应大于材料的最小折弯半径。在设计U型弯曲件时,两弯曲边最好长度相等,以免弯曲时产品偏 移而产生废品,如果因为结构设计不允许两边一样长,为保证产品在模 具中准确定位,应预先在设计时添加工艺定位孔,特别是多次折弯成 形的零件,必须设计工艺孔为定位基准,以减少累计误差,保证产品 质量,如图2-11所示。凸包是依靠材料的延伸使钣金件形成局部凹陷或凸起的冲压工序凸包与拉深是完全不同的冲压工艺,凸包中材料厚度的改变为费意图性 的,即厚度的少量改变是变形过程中形成的,不是设计指定的要求。
STM32H7系列QSPI内存映射模式与MPU配置冲突分析
本文分析了STM32H7系列QSPI内存映射模式与MPU配置冲突导致系统卡死的问题。通过解析内存保护管理单元机制,提供了MPU配置调整方案,包括禁用MPU或精细配置QSPI区域权限,确保内存映射模式正常访问外部Flash,避免HardFault错误。
PMD规则之Basic Rules
Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 <! /* Style
SAP-HR 模块 PPOSE 的详细信息标签页增强
步骤1:T-CODE : SE11 创建一个名为 HRI9106 的结构 命名:HRI + 91 + 两位数字。人事管理 - 组织管理 - 集成新信息类型 - 将信息类型添加为明细范围中的标签页。步骤6:SE51 查看 7000屏幕,修改屏幕属性 让其更美观。步骤3:T-CODE : SM30维护 T777I 表。步骤5:PPCI 新建 7000屏幕用于显示。标签页 IT 开头 + 信息类型 9106。步骤2:T-CODE : PPCI。步骤4:T-CODE : SPRO。
Android代码中遇到的一些警告或问题汇总
1. ‘catch’branch identical to‘instantiationexception’branch: Reports identical catch sections in try blocks under JDK 7. A quickfix is available to collapse the sections into a multi-catch section. ...
微信小程序:使用mqtt手机屏幕锁屏后导致中断问题,让mqtt在手机黑屏后依然能保持连接及持续后台运行接收或处理任务,详解微信小程序MQTT在应用退到后台或手机熄屏的情况下自动检测并重连【强制保活】
微信小程序切后台后MQTT连接无法维持,微信小程序MQTT一旦用户锁屏、切换到后台或手机熄屏,连接就会断开,导致无法继续监听和处理业务消息,微信小程序mqtt保活方案,微信小程序屏幕锁屏或息屏导致mqtt连接中断怎么办,如何解决MQTT不能黑屏持续连接的问题,微信小程序应用退到后台 MQTT连接断开问题解决,苹果ios手机,安卓手机,uniapp微信小程序mqtt断开怎么解决,后台应用怎么保活,uni-app中MQTT连接频繁断开如何解决?应用退到后台后MQTT连接断开以及常连接断连的问题,微信小程序、MQ
【新能源汽车测试工程师必看!DBC文件50条实战技巧,看懂这篇直接封神】
如果你是新能源汽车研发/测试工程师,还在为信号解析错误、报文找不到、DBC看不懂、实车故障复现不了头疼——那这篇文章,你一定要!在整车电控开发里,DBC = CAN总线的官方字典。没有DBC,报文就是一串乱码;读不懂DBC,测试寸步难行;用不好DBC,排查故障全靠猜。本文总结50条全网最实用、最贴近实车、最能解决问题的DBC技巧,从基础语法到新能源专用信号,从工具操作到故障排错,全部来自一线台架、实车、高压平台实战经验。不废话、不空谈、不玄学,全是能直接落地的硬货!
第77项:不要忽略异常
尽管这条建议看上去是显而易见的,但是它却常常被违反,因而值得重复提出来。当API的设计者声明一个方法将抛出某个异常的时候,它们是在试图告诉你某些事情。所以,不要忽略它!要忽略一个异常非常容易,只需要将方法调用通过try语句包围起来,并包含一个空的catch块: // Empty catch block ignores exception - Highly suspect! try { ...
数据挖掘实战-基于情感分析+网络语义分析+LDA主题分析对大唐不夜城用户评论进行文本分析
本研究基于去哪儿网和携程网的1888条大唐不夜城游客评论数据,运用Python进行文本分析。通过情感分析发现游客评价以积极为主(占比约70%),中性占20%,消极占10%。采用ROSTCM6软件进行社会网络语义分析,识别不同情绪下的高频词汇。使用LDA主题模型将评论划分为3个主题(夜景、表演、美食),并分析主题强度随时间变化趋势。实验包含数据采集、预处理、情感分析、语义网络分析和LDA建模等完整流程,为景区管理优化提供数据支持。源代码涵盖爬虫、数据处理和可视化分析的全套实现。
java try catch陷阱_java异常捕捉陷阱(内存泄漏,finally块,catch块,继承得到的异常)...
1. 异常捕捉的陷阱异常处理机制是java语言的特色之一,尤其是java语言的Checked异常,更是体现了java语言的严谨性:没有完善错误处理的代码根本不会被执行。对于Checked异常,java程序要么声明抛出,要么使用try……catch进行捕获。1.1 正确关闭资源的方式在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接,网络连接,磁盘文件等,打开这些物理资源之后必须显...
最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版
Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。
老版QQ原生表情gif动态
这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。
Java异常捕捉陷阱(内存泄漏,finally块,catch块,继承得到的异常)
1. 异常捕捉的陷阱 异常处理机制是java语言的特色之一,尤其是java语言的Checked异常,更是体现了java语言的严谨性:没有完善错误处理的代码根本不会被执行。对于Checked异常,java程序要么声明抛出,要么使用try……catch进行捕获。1.1 正确关闭资源的方式 在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接,网络连接,磁盘文件等,打开这些物
RU DOS版、EFI版32bit/64bit BIOS常用工具
DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。
java try catch陷阱_java异常捕捉陷阱(事务的异常,内存泄漏,finally块,catch块,继承得到的异常)...
事务的异常回滚默认spring只在发生未被捕获的runtimeexcetpion时才回滚。1、事务不是遇到所有异常都会回滚,默认只有遇到遇到运行异常(RuntimeException)和程序错误(Error)才会回滚,非运行异常必须在@Transactional 注解中使用 rollbackFor 属性来指定异常,比如:@Transactional(rollbackFor = Exception....
计算机控制技术及应用
《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。
java 异常处理 最佳_Java异常处理最佳实践及陷阱防范
前言不管在我们的工作还是生活中,总会出现各种“错误”,各种突发的“异常”。无论我们做了多少准备,多少测试,这些异常总会在某个时间点出现,如果处理不当或是不及时,往往还会导致其他新的问题出现。所以我们要时刻注意这些陷阱以及需要一套“最佳实践”来建立起一个完善的异常处理机制。正文异常分类首先,这里我画了一个异常分类的结构图。在JDK中,Throwable是所有异常的父类,其下分为”Error“和”Ex...
java陷进
1. 异常捕捉的陷阱 异常处理机制是java语言的特色之一,尤其是java语言的Checked异常,更是体现了java语言的严谨性:没有完善错误处理的代码根本不会被执行。对于Checked异常,java程序要么声明抛出,要么使用try……catch进行捕获。1.1 正确关闭资源的方式 在实际开发中,经常需要在程序中打开一些物理资源,如数据库连接,网络连接,磁盘文件等,打开这些物
基于字节码的统一异常上报实践
一、前言 二、异常介绍 2.1 认识异常 2.2 Java异常的分类 2.3 异常的处理流程 2.4 异常抛出与捕获的原则 2.5 认识try/catch/finally
Java架构治理新范式:用AST静态分析实现模块自治与契约验证
在微服务与模块化开发日益普及的今天,‘高内聚低耦合’常沦为口号,而真实系统中隐性依赖、跨模块契约违规、运行时类加载冲突等问题频发。AST(抽象语法树)作为编译前端的核心结构,能精准捕获设计意图——从import声明、new表达式到Lambda闭包中的类型引用,远超字节码或IDE级分析的粒度。它使架构约束可编程、可验证、可嵌入CI,将传统依赖评审转化为自动化守门机制。Smart-Bus项目正是这一理念的工程落地:通过AST驱动的调用图生成、作用域契约检查与热插拔状态迁移,实现了无Spring的轻量自治架构。本
Servlet监听器原理与实战:ServletContext、HttpSession、ServletRequest生命周期管理
Servlet监听器是Java Web应用中实现系统可观测性与生命周期治理的核心基础设施,其本质是对ServletContext、HttpSession和HttpServletRequest三大域对象及其属性变更的事件响应机制。基于Servlet规范,监听器通过回调方法在对象创建/销毁、属性增删改等关键节点触发,不干预流程但提供精准状态感知能力。技术价值在于保障资源启停安全、会话状态一致性和请求链路可审计性,广泛应用于连接池管理、用户登出清理、购物车变更追踪、性能监控等生产场景。本文深入剖析三类生命周期监听
Java AI项目监控实战:5类指标+4条告警打造可靠防线
在传统Java服务中,HTTP状态码、CPU与内存构成监控的“老三样”,但在大模型驱动的AI应用里,这些指标远远不够。可观测性工程的核心在于,通过指标、日志与追踪构建系统全貌。Micrometer作为Java生态的指标门面,搭配Prometheus的时序数据采集与Grafana的可视化能力,形成一套标准化的监控方案。它通过埋点记录请求量、错误率、延迟分位数、Token消耗、队列积压等关键数据,配合合理的告警规则,能在用户投诉前捕捉到模型静默退化、成本飙升等隐患。无论你是做RAG知识库问答、AI客服还是Age
Copilot实战协作协议:从代码补全到可信协作者
GitHub Copilot 不仅是智能代码补全工具,更是一种新型人机协作范式。其核心原理在于基于上下文的序列预测与语义对齐,技术价值体现在提升开发一致性、加速领域知识沉淀和强化工程合规性。在企业级Java/Python/TypeScript项目中,需通过语义锚点(如@domain、@security)、结构化反馈(@avoid/@require)和CI/CD合规检查链实现可控落地。本文聚焦真实生产环境中Copilot的语义注入、错误闭环训练与AI协作治理,解决‘能用’到‘敢用’的关键断层,尤其适用于Spr
974



被折叠的 条评论
为什么被折叠?



