java init clinit

今天看错误堆栈尽然发现一个以前没见过的Error ,java.lang.ExceptionInInitializerError

 

首先看下类原型

 

public class ExceptionInInitializerError extends LinkageError {

然后看下类说明

 * Signals that an unexpected exception has occurred in a static initializer .
 * An <code>ExceptionInInitializerError</code> is thrown to indicate that an
 * exception occurred during evaluation of a static initializer or the
 * initializer for a static variable.

 

接着看下LinkageError的来历

public  class LinkageError extends Error

 再看看他的类说明

 

 * Subclasses of <code>LinkageError</code> indicate that a class has
 * some dependency on another class ; however, the latter class has
 * incompatibly changed after the compilation of the former class.

 

顺便我们再来看下LinkageError的嫡系有哪些


java init clinit

好吧,这一家子的Error都是我们得罪不起的,他的孙子我们会经常见,而且好定位,儿子类型的错误不常见也不好直接定位。

 

说到这里,开始引入正题,看堆栈的时候,经常发现几个函数很特殊,例如堆栈里有如下2种函数

XxxClass.<init>

XxxxClass.<clinit>

 对比其他函数调用堆栈的显示

 

XxxClass.sayHello

XxxClass.sayBye

 最上面2个函数很特殊,用尖括号括起来,看下JVM的官方规范里的解释

 

 http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html

 3.9 Specially Named Initialization Methods

 

At the level of the Java virtual machine, every constructor (§2.12) appears as an instance initialization method that has the special name <init>. This name is supplied by a compiler. Because the name <init> is not a valid identifier, it cannot be used directly in a program written in the Java programming language. Instance initialization methods may be invoked only within the Java virtual machine by the invokespecial instruction, and they may be invoked only on uninitialized class instances. An instance initialization method takes on the access permissions (§2.7.4) of the constructor from which it was derived. 


A class or interface has at most one class or interface initialization method and is initialized (§2.17.4) by invoking that method. The initialization method of a class or interface is static and takes no arguments. It has the special name <clinit>. This name is supplied by a compiler. Because the name <clinit> is not a valid identifier, it cannot be used directly in a program written in the Java programming language. Class and interface initialization methods are invoked implicitly by the Java virtual machine; they are never invoked directly from any Java virtual machine instruction, but are invoked only indirectly as part of the class initialization process

 

   搬出这个规范以及上面啰嗦的Error问题 是想说,以后看到堆栈,我们应该能第一时间就能明白错误大致发生在什么地方,大概原因是什么,了解这些,对加速定位问题是有帮助的。

你可能感兴趣的:(java)