JDK Throwable
Throwable
1. 使用大量数组和List常量: private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
2. 使用静态内部类
3. 拥有自身类的成员对象: cause, suppressedExceptions
public class Throwable implements Serializable {
// Array & List常量
private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
private static final List<Throwable> SUPPRESSED_SENTINEL = Collections
.unmodifiableList(new ArrayList<Throwable>(0));
private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
private Throwable cause = this;
// 静态内部内
private static class SentinelHolder {
public static final StackTraceElement STACK_TRACE_ELEMENT_SENTINEL = new StackTraceElement("", "", null, Integer.MIN_VALUE);
// 输出时当stackTrace为空时,即赋予该值
public static final StackTraceElement[] STACK_TRACE_SENTINEL = new StackTraceElement[] { STACK_TRACE_ELEMENT_SENTINEL };
}
public final synchronized void addSuppressed(Throwable exception) {
if (exception == this)
throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE, exception);
if (exception == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE);
if (suppressedExceptions == null)
return;
if (suppressedExceptions == SUPPRESSED_SENTINEL) // suppressedExceptions等于初始值,即创建list
suppressedExceptions = new ArrayList<>(1);
suppressedExceptions.add(exception);
}
public void printStackTrace(PrintWriter s) {
printStackTrace(new WrappedPrintWriter(s)); // 使用静态内部类
}
private void printStackTrace(PrintStreamOrWriter s) {
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);
for (Throwable se : getSuppressed())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu);
}
}
private abstract static class PrintStreamOrWriter {
abstract Object lock();
abstract void println(Object o);
}
private static class WrappedPrintStream extends PrintStreamOrWriter {
private final PrintStream printStream;
WrappedPrintStream(PrintStream printStream) {
this.printStream = printStream;
}
Object lock() {
return printStream;
}
void println(Object o) {
printStream.println(o);
}
}
private synchronized StackTraceElement[] getOurStackTrace() {
if (stackTrace == UNASSIGNED_STACK || (stackTrace == null && backtrace != null){
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;
}
private void printEnclosedStackTrace(PrintStreamOrWriter s,
StackTraceElement[] enclosingTrace, String caption, String prefix, Set<Throwable> dejaVu) {
assert Thread.holdsLock(s.lock());
if (dejaVu.contains(this)) {
s.println("\t[CIRCULAR REFERENCE:" + this + "]");
} else {
dejaVu.add(this);
// Compute number of frames in common between this and enclosing
StackTraceElement[] trace = getOurStackTrace();
int m = trace.length - 1;
int n = enclosingTrace.length - 1;
while (m >= 0 && n >= 0 && trace[m].equals(enclosingTrace[n])) {
m--;
n--;
}
int framesInCommon = trace.length - 1 - m;
// Print our stack trace
s.println(prefix + caption + this);
for (int i = 0; i <= m; i++)
s.println(prefix + "\tat " + trace[i]);
if (framesInCommon != 0)
s.println(prefix + "\t... " + framesInCommon + " more");
// Print suppressed exceptions, if any
for (Throwable se : getSuppressed())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, prefix + "\t", dejaVu);
// Print cause, if any
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, prefix, dejaVu);
}
}
public final synchronized Throwable[] getSuppressed() {
if (suppressedExceptions == SUPPRESSED_SENTINEL ||
suppressedExceptions == null)
return EMPTY_THROWABLE_ARRAY;
else
return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
}
public synchronized Throwable getCause() {
return (cause==this ? null : cause);
}
}
JDK Throwable的更多相关文章
- JDK动态代理
一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...
- JDK动态代理实现原理
之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白.比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的.直到看了他的文章才彻底明白,附网址:htt ...
- 静态代理和利用反射形成的动态代理(JDK动态代理)
代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...
- 基于Spring AOP的JDK动态代理和CGLIB代理
一.AOP的概念 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...
- Spring中的JDK动态代理
Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...
- 模仿mybatis,用jdk proxy实现接口
在mybatis中,我们都只需要定义一个mapper接口,但并不需要对它进行任务实现.只要有对就的mapper.xml文件就可以访问数据库.那么,没有接口的访问是如何实现的呢. 答案就是JDK pro ...
- AOP学习心得&jdk动态代理与cglib比较
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- springmvc 动态代理 JDK实现与模拟JDK纯手写实现。
首先明白 动态代理和静态代理的区别: 静态代理:①持有被代理类的引用 ② 代理类一开始就被加载到内存中了(非常重要) 动态代理:JDK中的动态代理中的代理类是动态生成的.并且生成的动态代理类为$Pr ...
- Java 的静态代理 动态代理(JDK和cglib)
转载:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是 ...
随机推荐
- JVM实用参数(二)参数分类和即时(JIT)编译器诊断
JVM实用参数(二)参数分类和即时(JIT)编译器诊断 作者: PATRICK PESCHLOW 原文地址 译者:赵峰 校对:许巧辉 在这个系列的第二部分,我来介绍一下HotSpot J ...
- 关于android通过shell修改文件权限的学习
首先是文件的读写属性(下图): 要通过shel命令l修改文件权限: 1.首先在cmd里输入adb shell 命令进入编辑模式 2.用cd命令进入到想要修改的文件目录,不知道的时候可以用ls 命令列表 ...
- QGraphicsScene绘制网格背景
博客转载自:https://blog.csdn.net/u010177010/article/details/51496038 //两条轴线QPolygonF myPolygon1; myPolygo ...
- p3163 [CQOI2014]危桥
传送门 分析 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string ...
- scala中的self type
scala目前的书籍有两<快学scala>和<scala编程>.资料确实不多,对这个语法使用只能结合使用进行理解. 先看源码: private[spark] trait Act ...
- 日常学习随笔-自定义了一个MyArrayListDefin集合(数组扩容+迭代器+JDK1.8新方法+详细说明)
一.自定义了一个ArrayList的模拟集合(源码+详细说明) 前段时间分析了下ArrayList集合的源码,总觉得如果不自己定义一个的话,好像缺了点什么,所以有了如下的代码. 代码可以说是逐行注释了 ...
- 在WindowsXP+IIS5.1下运行ASP.NET MVC3
1. 安装ASP.NET MVC3 http://download.microsoft.com/download/1/4/C/14C0533D-2299-42CD-898C-10AA5156E243/ ...
- appium自动化安装(二)
第二节 安装Android开发环境 如果你的环境是MAC那么可以直接跳过这一节.就像我们在用Selenium进行web自动化测试的时候一样,我们需要一个浏览器来执行测试脚本.那么移动端自动化测试,我 ...
- Docker 的优势
下面我们主要从Docker对业务架构和生产实践的角度来分析. 随着业务规模的逐渐扩大,产品复杂度也随着增加,企业需要解决快速迭代.高可靠和高可用等问题,一个自然的选择是服务化的拆分,把一个单体架构拆分 ...
- nginx添加缓存以及判断是否缓存生效
location ~.*\.(js|css|html|png|jpg|gif)$ { expires 3d; } expires 3d; //表示缓存3天 expires 3h; //表示 ...