[编织消息框架][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核心技术]数值与逻辑分离
为什么要分离? 业务需求是不停地变,如果把条件写进代码里,当用户需求变时要改代码发版本更新才能生效,这过程无疑是漫长的 就算是在开发期,不停的变开发者精力耗光在沟通,小修改上,无法专注逻辑部分 分离的 ...
随机推荐
- memcache调整value大小限制
> *事件背景: 当Redis有问题时按预案就会切换到本机memcache,但是我们首页 key:value现 在是1.5M同时memcache item限制是1M,导致首页写入memcache ...
- java 后台代码调用接口
import com.jiuqu.jollykeys.common.util.JsonUtil;import java.io.UnsupportedEncodingException;import j ...
- spring boot系列03--spring security (基于数据库)登录和权限控制(上)
这篇打算写一下登陆权限验证相关 说起来也都是泪,之前涉及权限的比较少所以这次准备起来就比较困难. 踩了好几个大坑,还好最终都一一消化掉(这是废话你没解决你写个什么劲
- 利用qq设置个性化的域名邮箱
首先有域名.先去注冊先,国内有非常多域名交易平台.我是在易名中国网上注冊的一个域名,Lios.top,因为这个域名价值非常低.一年才 10元,价格非常实惠. 下一步就是去qq邮箱的设置里,找到账户,然 ...
- oracle用户被锁定
sqlplus sys/password@localhost:1521/cmsx as sysdba SQL*Plus: Release 11.2.0.1.0 Production on 星期一 7月 ...
- BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序 Excel Services中新功能
BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序 Excel Services中新功能 从S ...
- ASP.NET Core 异常重试组件 Polly
Polly 是一种 .NET 弹性和瞬态故障处理库,允许开发人员以流畅和线程安全的方式表达策略,如重试,断路器,超时,隔离隔离和备用,Polly 适用于 .NET 4.0,.NET 4.5 和 .NE ...
- 调用接口http封装
public static String httpHandler(String URL,String xml){ try { URL url=new URL(URL); URLConnection c ...
- 如何解决更新被拒绝,因为远程版本库包含您本地尚不存在的提交。这通常是因为另外 提示:一个版本库已向该引用进行了推送。再次推送前,您可能需要先整合远程变更 提示:(如 'git pull ...')。
不要通过网页提交,通过网页提交一次,然后在终端再次push的时候,会认为网上代码仓库已经被其他地方提交过一次代码,此时会拒绝终端push 这个时候只能是pull,然后才能再次在终端提交. 也就是说,避 ...
- redis的事务(简单介绍)
1.简单描述 redis对事务的支持目前还是比较简单.redis只能保证一个client发起的事务中的命令是可以连续的执行,而中间不会插入其他client的命令.由于redis是但现场来处理所有cli ...