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的更多相关文章

  1. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  2. JDK动态代理实现原理

    之前虽然会用JDK的动态代理,但是有些问题却一直没有搞明白.比如说:InvocationHandler的invoke方法是由谁来调用的,代理对象是怎么生成的.直到看了他的文章才彻底明白,附网址:htt ...

  3. 静态代理和利用反射形成的动态代理(JDK动态代理)

    代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...

  4. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  5. Spring中的JDK动态代理

    Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...

  6. 模仿mybatis,用jdk proxy实现接口

    在mybatis中,我们都只需要定义一个mapper接口,但并不需要对它进行任务实现.只要有对就的mapper.xml文件就可以访问数据库.那么,没有接口的访问是如何实现的呢. 答案就是JDK pro ...

  7. AOP学习心得&jdk动态代理与cglib比较

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  8. springmvc 动态代理 JDK实现与模拟JDK纯手写实现。

    首先明白 动态代理和静态代理的区别: 静态代理:①持有被代理类的引用  ② 代理类一开始就被加载到内存中了(非常重要) 动态代理:JDK中的动态代理中的代理类是动态生成的.并且生成的动态代理类为$Pr ...

  9. Java 的静态代理 动态代理(JDK和cglib)

    转载:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是 ...

随机推荐

  1. CustomProgressDialog

    1 ,布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...

  2. day70-oracle 12-触发器

    查询是没有触发器的.trigger是一个数据库的对象.PL/SQL程序是在我插入之前执行还是在插入之后执行?触发器类似于java中的监听器. 监听插入操作,执行一段PLSQL程序. 禁止在非工作时间插 ...

  3. 用于.NET环境的时间测试(转)

    用于.NET环境的时间测试   在.NET环境中,衡量运行完整算法所花费的时间长度,需要考虑很多 需要考虑很多种情况 ,如:程序运行所处的线程以及无用单位收集(GC垃圾回收). 在程序执行过程中无用单 ...

  4. 使用Javascript Ajax 通信操作JSON数据 [上]

    以前只是知道json的格式而已,也做过的是从数据库获得数据然后弄成json的格式然后赋给HighCharts生成曲线,先把数据库的数据使用array()函数转换成数组,然后使用json_encode( ...

  5. IFC4 在线参考手册

    国内地址1:http://www.vfkjsd.cn/ifc/ifc4/index.htm 国内地址2:http://www.bim-times.com/ifc/ifc4/index.htm 官方地址 ...

  6. Linux 查看设置系统语言

    一.简介 在Linux的系统中经常碰到字符集导致的错误,本文总结了设置修改系统语言环境的方法步骤. 二.操作步骤 执行如下指令,查看当前使用的系统语言 echo $LANG 执行如下指令,查看系统安装 ...

  7. C++中的内存重叠问题

    内存重叠,直到做到一个笔试题才知道了什么是内存重叠.先上题目吧,是一个淘宝的笔试题,当时有点懵,不知道这个名词是啥子意思. 题目:补充下面函数代码: 如果两段内存重叠,用memcpy函数可能会导致行为 ...

  8. 《Effective Java》第3章 对于所有对象都通用的方法

    第8条:覆盖equals时请遵守通用约定 覆盖equals方法看起来似乎很简单,但是有许多覆盖方式会导致错误,并且后果非常严重.最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,类的每 ...

  9. 【IIS】编译器失败,错误代码为 -2146232576

    把新写的 ASP.NET MVC 代码发布到 阿里云虚拟机后,报如下错误: 编译器失败,错误代码为 -2146232576 参考了 iis 错误 -2146232576 和 asp.net mvc5本 ...

  10. Hadoop单机/伪分布式集群搭建(新手向)

    此文已由作者朱笑笑授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 本文主要参照官网的安装步骤实现了Hadoop伪分布式集群的搭建,希望能够为初识Hadoop的小伙伴带来借鉴意 ...