[编织消息框架][JAVA核心技术]异常基础
Java异常体系结构
Thorwable类所有异常和错误的超类,有两个子类Error和Exception,分别表示错误和异常。
其中异常类Exception又分为运行时异常(RuntimeException)和编译时异常(checked Exception),
下面将详细讲述这些异常之间的区别与联系:
1.Error与Exception
Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等。这些异常发生时, Java虚拟机(JVM)一般会选择线程终止。
Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。 程序中应当尽可能去处理这些异常。
2.运行时异常和编译时异常
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,
这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的。
编译时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。
从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。
3.异常链
设计目的是清晰知道程序出错调用流程,也就是传递性,一般只关心第一个跟最后一个异常信息
源码分析
分三部份:
1.构造异常
2.注册当前异常到异常列表深度坐标
3.打印异常链
第一部份:每次构造异常类时会调用顶级类Throwable构造方法
public Exception(String message) {
super(message);
} public Exception(String message, Throwable cause) {
super(message, cause);
}
public Throwable(String message) {
fillInStackTrace();
detailMessage = message;
} public Throwable(String message, Throwable cause) {
fillInStackTrace();
detailMessage = message;
this.cause = cause;
}
第二部份:注册到异常列表
public synchronized Throwable fillInStackTrace() {
if (stackTrace != null ||
backtrace != null /* Out of protocol state */ ) {
//插入异常列表 0 代表插入到第一,也就是说最后一个异常放到头部
fillInStackTrace(0);
stackTrace = UNASSIGNED_STACK;
}
return this;
} private native Throwable fillInStackTrace(int dummy);
第三部份:打印异常链,由于最后异常注册到头部,所以循环输出顺序是从尾到头
public void printStackTrace() {
printStackTrace(System.err);
} public void printStackTrace(PrintStream s) {
printStackTrace(new WrappedPrintStream(s));
} private void printStackTrace(PrintStreamOrWriter s) {
// Guard against malicious overrides of Throwable.equals by
// using a Set with identity equality semantics.
Set<Throwable> dejaVu =
Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
dejaVu.add(this); synchronized (s.lock()) {
// Print our stack trace
s.println(this);
StackTraceElement[] trace = getOurStackTrace();
for (StackTraceElement traceElement : trace)
s.println("\tat " + traceElement); // Print suppressed exceptions, if any
for (Throwable se : getSuppressed())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu); // Print cause, if any
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
}
} public StackTraceElement[] getStackTrace() {
return getOurStackTrace().clone();
} private synchronized StackTraceElement[] getOurStackTrace() {
// Initialize stack trace field with information from
// backtrace if this is the first call to this method
if (stackTrace == UNASSIGNED_STACK ||
(stackTrace == null && backtrace != null) /* Out of protocol state */) {
int depth = getStackTraceDepth();
stackTrace = new StackTraceElement[depth];
for (int i=0; i < depth; i++)
stackTrace[i] = getStackTraceElement(i);
} else if (stackTrace == null) {
return UNASSIGNED_STACK;
}
return stackTrace;
}
打印异常链
4.追踪出错代码
第一个输出是最后一个异常:也就是说可以追踪到最外层出错方法
最后一个输出是第一个异常:也就是说追踪到出错的源头
来个示例说明:
package com.eyu.onequeue; public class TestException {
public static void main(String[] args) {
new TestException().demo();
} public void a() {
try {
b();
} catch (Exception e) {
throw new RuntimeException("call a", e);
} } public void b() {
try {
c();
} catch (Exception e) {
throw new RuntimeException("call b", e);
}
} public void c() {
throw new RuntimeException("call c");
} public void demo() {
a();
}
}
Exception in thread "main" java.lang.RuntimeException: call a
at com.eyu.onequeue.TestException.a(TestException.java:12)
at com.eyu.onequeue.TestException.demo(TestException.java:30)
at com.eyu.onequeue.TestException.main(TestException.java:5)
Caused by: java.lang.RuntimeException: call b
at com.eyu.onequeue.TestException.b(TestException.java:21)
at com.eyu.onequeue.TestException.a(TestException.java:10)
... 2 more
Caused by: java.lang.RuntimeException: call c
at com.eyu.onequeue.TestException.c(TestException.java:26)
at com.eyu.onequeue.TestException.b(TestException.java:19)
... 3 more
c方法是出错的源头,a方法是调用者
小提示:当异常信息太多时,过滤条件以项目包名或类名能快速定位出错源头,一般是应用程序逻辑出错
下节利用异常开发项目
最后给出jdk常见异常
[编织消息框架][JAVA核心技术]异常基础的更多相关文章
- [编织消息框架][JAVA核心技术]异常应用
QException是项目业务异常基类 按模块划分子类异常,方便定位那块出错 有个来源码属性code作用定位某个功能处理出错逻辑,数字类型节省内存空间,同时减少创建子类的子类 QSocketExcep ...
- [编织消息框架][JAVA核心技术]annotation基础
应用动态代理技术要先掌握annotation技术 注解是JDK1.5之后才有的新特性,JDK1.5之后内部提供的三个注解 @Deprecated 意思是“废弃的,过时的” @Override 意思是“ ...
- [编织消息框架][JAVA核心技术]动态代理应用12-总结
动态代理这篇比较长,是框架组成的重要基础 回顾下学到的应用技术 1.异常应用 2.annotation技术 3.数值与逻辑分享 4.jdk.cglib.javassist等动态代理技术 5.懒处理.预 ...
- [编织消息框架][JAVA核心技术]动态代理应用4
基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...
- [编织消息框架][JAVA核心技术]动态代理应用4-annotationProcessor
基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...
- [编织消息框架][JAVA核心技术]动态代理应用5-javassist
基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...
- [编织消息框架][JAVA核心技术]动态代理介绍
由于java是种强类型静态语言,在执行时无法动态生成代码,静态语言基本都有这特性 动态生成代码有几种好处,也是弱类型语言的优点 1.部份逻辑可以实现热更新 2.远程调用实现非常适合 3.能动态生成扩展 ...
- [编织消息框架][JAVA核心技术]动态代理应用1
前面几篇介绍,终于到了应用阶段啦,我们来做一个RPC来加强学过的知识 做基础核心时先确定解决什么问题,提供什么服务,同将来扩展等 rpc 分两部份,一个是调用者,另一方是服务提供者 调用者只关心那个服 ...
- [编织消息框架][JAVA核心技术]数值与逻辑分离
为什么要分离? 业务需求是不停地变,如果把条件写进代码里,当用户需求变时要改代码发版本更新才能生效,这过程无疑是漫长的 就算是在开发期,不停的变开发者精力耗光在沟通,小修改上,无法专注逻辑部分 分离的 ...
随机推荐
- keepalived实现服务高可用
第1章 keepalived服务说明 1.1 keepalived是什么? Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可 ...
- arguments,caller,callee之理解
arguments对象代表正在执行的函数和调用它的函数的参数,arguments是一个不是数组但类似 数组的对象,它具有同数组一样的访问性质及方式,可以由arguments[n]来访问对应单个参数的值 ...
- 记一次高并发场景下.net监控程序数据上报的性能调优
最近在和小伙伴们做充电与通信程序的架构迁移.迁移前的架构是,通信程序负责接收来自充电集控设备的数据实时数据,通过Thrift调用后端的充电服务,充电服务收到响应后放到进程的Queue中,然后在管理线程 ...
- 通过c# 实现mysql 数据库的备份和附加
近期涉及到通过c# 对mysq数据库的备份和附件功能 由于mysql 有类似的备份和附加的cmd命令.可是一直没用过,今天实践了下,感觉效率挺快.比自己写的效率高.以下我列出c#调用mysql的备份和 ...
- ListView原理
表明转载自http://blog.csdn.net/iispring/article/details/50967445 在自己定义Adapter时,我们经常会重写Adapter的getView方法,该 ...
- immutable日常操作之深入API
写在前面 本文只是个人在熟悉Immutable.js的一些个人笔记,因此我只根据我自己的情况来熟悉API,所以很多API并没有被列举到,比如常规的push/map/filter/reduce等等操作, ...
- inline-block并列排序时候的影响
当两个设置了inline-block属性的元素并列排放时,它们的位置能够互相影响. 元素结构: <div class="container"> <div clas ...
- 自学Zabbix3.5.3-监控项item-key
1. 温习 Zabbix server是Zabbix软件的中心进程. Server执行polling和trapping来采集数据,评估是否触发触发器,发送报警给用户.它是Zabbix agent和pr ...
- 自学Python5.1-模块简介
模块简介 在C语言中如果要引用sqrt这个函数,必须用语句"#include<math.h>"引入math.h这个头文件,否则是无法正常进行调用的.那么在Python中 ...
- javascript中的双向绑定
阅读目录 一:发布订阅模式实现数据双向绑定 二:使用Object.defineProperty 来实现简单的双向绑定. 前言: 双向数据绑定的含义:可以将对象的属性绑定到UI,具体的说,我们有一个对象 ...