目录
- 引出
- 异常
- 建议110:提倡异常封装;
- 建议111:采用异常链传递异常
- 建议112:受检异常尽可能转化为非受检异常
- 建议113:不要在finally块中处理返回值
- 建议114:不要在构造函数中抛异常
- 建议115:使用Throwable获得栈信息
- 建议116:异常只为异常服务
- 建议117:多使用异常,把性能问题放一边
- 深入认识JVM
- JVM内存分配,类加载
- 创建对象的4种方法总结
- 垃圾回收GC
- JVM调优,Arthas使用
- 认识多线程
- 创建多线程方法+了解线程池
- 多线程下-1非原子性问题即解决
- 再论线程,创建、生命周期
- 总结
引出
程序人生——Java异常使用建议
异常
建议110:提倡异常封装;
- 异常封装有三方面的优点:
- 1、提高系统的友好性;
- 2、提高系统的可维护性;
- 3、解决Java异常机制本身的缺陷;
建议111:采用异常链传递异常
- 责任链模式(Chain of Responsibility),目的是将多个对象连城一条链,并沿着这条链传递该请求,直到有对象处理它为止,异常的传递处理也应该采用责任链模式
建议112:受检异常尽可能转化为非受检异常
- 受检异常威胁到系统的安全性、稳定性、可靠性、正确性时、不能转为非受检异常)(受检异常(Checked Exception),非受检异常(Unchecked Exception),受检异常时正常逻辑的一种补偿处理手段,特别是对可靠性要求比较高的系统来说,在某些条件下必须抛出受检异常以便由程序进行补偿处理,也就是说受检异常有合理的存在理由。但是受检异常有不足的地方:1、受检异常使接口声明脆弱;2、受检异常是代码的可读性降低,一个方法增加了受检异常,则必须有一个调用者对异常进行处理。受检异常需要try…catch处理;3、受检异常增加了开发工作量。避免以上受检异常缺点办法:将受检异常转化为非受检异常
建议113:不要在finally块中处理返回值
- 在finally块中加入了return语句会导致以下两个问题:1、覆盖了try代码块中的return返回值;2、屏蔽异常,即使throw出去了异常,异常线程会登记异常,但是当执行器执行finally代码块时,则会重新为方法赋值,也就是告诉调用者“该方法执行正确”,没有发生异常,于是乎,异常神奇的消失了
建议114:不要在构造函数中抛异常
- Java异常机制有三种:1、Error类及其子类表示的是错误,它是不需要程序员处理的也不能处理的异常,比如VirtualMachineError虚拟机错误,ThreadDeath线程僵死等;2、RuntimeException类及其子类表示的是非受检异常,是系统可能抛出的异常,程序员可以去处理,也可以不处理,最经典的是NullPointerException空指针异常和IndexOutOfBoundsException越界异常;3、Exception类及其子类(不包含非受检异常)表示的是受检异常,这是程序员必须要处理的异常,不处理则程序不能通过编译,比如IOException表示I/O异常,SQLException数据库访问异常。一个对象的创建过程要经过内存分配、静态代码初始化、构造函数执行等过程,构造函数中是否允许抛出异常呢?从Java语法上来说,完全可以,三类异常都可以,但是从系统设计和开发的角度分析,则尽量不要在构造函数中抛出异常
建议115:使用Throwable获得栈信息
- 在出现异常时(或主动声明一个Throwable对象时),JVM会通过fillInStackTrace方法记录下栈信息,然后生成一个Throwable对象,这样就能知道类间的调用顺序、方法名称以及当前行号等
建议116:异常只为异常服务
- 异常原本是正常逻辑的一个补充,但有时候会被当前主逻辑使用。异常作为主逻辑有问题:1、异常判断降低了系统性能;2、降低了代码的可读性,只有详细了解valueOf方法的人才能读懂这样的代码,因为valueOf抛出的是一个非受检异常;3、隐藏了运行期可能产生的错误,catch到异常,但没有做任何处理
建议117:多使用异常,把性能问题放一边
- new一个IOException会被String慢5倍:因为它要执行fillInStackTrace方法,要记录当前栈的快照,而String类则是直接申请一个内存创建对象。而且,异常类是不能缓存的。但是异常是主逻辑的例外逻辑,会让方法更符合实际的处理逻辑,同时使主逻辑更加清晰,可让正常代码和异常代码分离、能快速查找问题(栈信息快照)等
深入认识JVM
JVM内存分配,类加载
Java进阶(1)——JVM的内存分配 & 反射Class类的类对象 & 创建对象的几种方式 & 类加载(何时进入内存JVM)& 注解 & 反射+注解的案例
创建对象的4种方法总结
Java进阶(4)——结合类加载JVM的过程理解创建对象的几种方式:new,反射Class,克隆clone(拷贝),序列化反序列化
垃圾回收GC
Java进阶(垃圾回收GC)——理论篇:JVM内存模型 & 垃圾回收定位清除算法 & JVM中的垃圾回收器
简介:本篇博客介绍JVM的内存模型,对比了1.7和1.8的内存模型的变化;介绍了垃圾回收的语言发展;阐述了定位垃圾的方法,引用计数法和可达性分析发以及垃圾清除算法;然后介绍了Java中的垃圾回收器,由串行、到并行再到并发,最后到G1的演变;最后给出了垃圾回收器的对比和使用指引。
JVM调优,Arthas使用
- Java进阶(JVM调优)——阿里云的Arthas的使用 & 安装和使用 & 死锁查找案例,重新加载案例,慢调用分析
- Java进阶(JVM调优)——JVM调优参数 & JDK自带工具使用 & 内存溢出和死锁问题案例 & GC垃圾回收
认识多线程
创建多线程方法+了解线程池
Java进阶(5)——创建多线程的方法extends Thread和implements Runnable的对比 & 线程池及常用的线程池
多线程下-1非原子性问题即解决
Java进阶(6)——抢购问题中的数据不安全(非原子性问题)& Java中的synchronize和ReentrantLock锁使用 & 死锁及其产生的条件
再论线程,创建、生命周期
Java进阶(再论线程)——线程的4种创建方式 & 线程的生命周期 & 线程的3大特性 & 集合中的线程安全问题
主要内容:
1.线程创建的方式,继承Thread类,实现Runable接口,实现Callable接口,采用线程池;
2.线程生命周期: join():运行结束再下一个, yield():暂时让出cpu的使用权,deamon():守护线程,最后结束,sleep():如果有锁,不会让出;
3.线程3大特性,原子性,可见性,有序性;
4.list集合中线程安全问题,hash算法问题;
总结
程序人生——Java异常使用建议