Stack Overflow 上的一个问题:Java: What is the difference between <init> and <clinit>?

 
JVM Specification 8, 2.9. Special Methods 是这样描述这两个方法的:
At the level of the Java Virtual Machine, every constructor written in the Java programming language (JLS §8.8) 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 (§invokespecial), and they may be invoked only on uninitialized class instances. An instance initialization method takes on the access permissions (JLS §6.6) of the constructor from which it was derived.

A class or interface has at most one class or interface initialization method and is initialized (§5.5) by invoking that method. The initialization method of a class or interface has the special name <clinit>, takes no arguments, and is void (§4.3.3).

Other methods named <clinit> in a class file are of no consequence. They are not class or interface initialization methods. They cannot be invoked by any Java Virtual Machine instruction and are never invoked by the Java Virtual Machine itself.

In a class file whose version number is 51.0 or above, the method must additionally have its ACC_STATIC flag (§4.6) set in order to be the class or interface initialization method.

This requirement was introduced in Java SE 7. In a class file whose version number is 50.0 or below, a method named <clinit> that is void and takes no arguments is considered the class or interface initialization method regardless of the setting of its ACC_STATIC flag.

The name <clinit> 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.

 
在编译生成 class file 时,JVM 会自动生成两个方法,一个是类的初始化方法 <clinit>, 另一个是实例的初始化方法 <init>。
<clinit>:在 JVM 第一次加载class文件时调用,包括静态变量初始化语句和静态块的执行;
<init>:在实例创建出来的时候调用,包括调用new操作符;调用 Class 或 java.lang.reflect.Constructor 对象的 newInstance() 方法;调用任何现有对象的 clone() 方法;通过 java.io.ObjectInputStream 类的 getObject() 方法反序列化。
 
 

最新文章

  1. GRANT/SELECT View时的遭遇ORA-01720和ORA-01031错误
  2. hibernate复合主键
  3. 【管理心得之三十八】如果“Q”不是高富帅,也吸引不了白富美“A”
  4. 安卓和ios的lineheight的不一样如何解决?
  5. [题解]某模拟题(USACO月赛部分题+noip2005部分题)
  6. ylbtech-LanguageSamples-Yield
  7. Python学习(二) 运行Python,编译Python
  8. eclipse加入辅助线,配合代码格式化使用
  9. 手机自动化测试:appium源码分析之bootstrap四
  10. windows embedded compact 2013 正版免费下载
  11. MFC,ADO方式实现数据库操作
  12. 《java入门第一季》之tcp协议下的网络编程c/s实现通信交互
  13. 详解 HTTPS、TLS、SSL、HTTP区别和关系
  14. Ubuntu 16.04下vsftpd 安装配置实例
  15. 安卓开发之自定义一个view弹出框
  16. Linux下搭建ruby on rails环境
  17. atomic 包、synchronized | Java 中线程安全
  18. [代码]--ORA-01745: 无效的主机/绑定变量名 ORA-00917: 缺失的逗号 oracle日期格式错误
  19. Install SVN (Subversion) Server on Fedora 20/19, CentOS/Red Hat (RHEL) 6.5/5.10
  20. 在ant中将依赖jar包一并打包的方法

热门文章

  1. Docker 搭建一个Docker应用栈
  2. NCBI
  3. HTML图片热区 map area 标签
  4. 元素 &quot;context:component-scan&quot; 的前缀 &quot;context&quot; 未绑定的解决方案
  5. js多个&lt;ul&gt;相应不同的点击事件
  6. Windows 配置Apache以便在浏览器中运行Python script的CGI模式
  7. codevs1907 方格取数 3
  8. $.ajax应用之请求头headers
  9. 伪Excel导出新版代码
  10. 马拉车——模版+KMP——模版