Java接口的初始化
背景
接口与类真正有所区别的是前面讲述的四种“有且仅有”需要开始初始化场景中的第三种:当一个类在初始化时,要求其父类全部都已经初始化过了,但是一个接口在初始化时,并不要求其父接口全部都完成了初始化,只有在真正使用到父接口的时候(如引用接口中定义的常量)才会初始化。 ——《深入理解Java虚拟机:JVM高级特性与最佳实践》
这里讲到引用接口中定义的常量会初始化接口,但是书中也写到引用类中的常量不会导致类被初始化,因为编译阶段已经将常量移动到常量池中了,两者的说法有一些矛盾让我很困惑。
public class InterfaceInitTest {
public static void main(String[] args) {
System.out.println(Interface.CONSTANT_INT);
}
}
interface Interface {
int CONSTANT_INT = 1;
Object CONSTANT_OBJECT = new Object();
Object CONSTANT_OBJECT2 = new Object() {
{
System.out.println("interface init");
}
};
}
1
Process finished with exit code 0
可以看到没有接口并没有被初始化,这和我理解的是一样的,引用类中的常量不会导致类被初始化,引用接口中的常量也不会被初始化。
但是稍微修改一下main函数的代码
public class InterfaceInitTest {
public static void main(String[] args) {
System.out.println(Interface.CONSTANT_OBJECT);
}
}
interface init
java.lang.Object@14ae5a5Process finished with exit code 0
可以看到同样是引用接口中的常量,有时候接口又会被初始化。
通过在网上找到的一篇文章ConstantValue属性,里面提到常量池中只能引用到基本类型和String类型的字面量。这也就解答了我的困惑:类和接口在被引用常量的时候是否被初始化,取决于这个常量能够在编译时被放进常量池中(排除不支持的类型和运行时常量)。
接口初始化的规则
通过测试发现,以下几种情况接口会被初始化:
- 调用接口中不在常量池中的常量(对static字段的引用引发的初始化只会初始化实际定义的接口(尽管可以通过实现类,子接口的名称进行引用(而接口中的static方法不能被继承)))
- 调用接口中的静态方法
- 当初始化一个类时,将初始化这个类实现的所有的包含default方法的接口和超接口
java.lang.reflect可能会导致接口初始化
初始化接口本身不会导致任何超接口的初始化(注意和第3条的区别)
对于这个问题我查阅了很多书籍和文章,都有讲得不太清楚的地方,所以不太确定结论是否正确,文章存在的疏漏读者也可以评论指正。
Java接口的初始化的更多相关文章
- [Java] 类和接口的初始化步骤 - 继承方面
类和接口在初始化化时,处理继承层级的方法不一样. 类继承的初始化:通过引用 static 字段,触发某个类的初始化,则声明该字段的类,以及该类的父类被初始化. 接口继承的初始化:通过引用 static ...
- java接口
一.定义 Java接口(Interface),是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为( ...
- Java系列笔记(1) - Java 类加载与初始化
目录 类加载器 动态加载 链接 初始化 示例 类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用. 每个类编译后产生一个 ...
- OpenCV4Android开发之旅(一)----OpenCV2.4简介及 app通过Java接口调用OpenCV的示例
转自: http://blog.csdn.net/yanzi1225627/article/details/16917961 开发环境:windows+ADT Bundle+CDT+OpenCV-2 ...
- Java中类的初始化
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.其中验证.准备.解析3个部分统称为连接.类加载的过程包括了加载.验证.准备.解 ...
- [Java] 类的初始化步骤
前言 类的初始化过程,可在多线程环境下进行的,为了简化,本文介绍的单线程情况下的类初始化步骤. 此外,继承情况下的顺序不是本文焦点,本文重点在于一个类的内部字段的初始化顺序.想了解继承情况下的初始化情 ...
- Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...
- Java 类加载与初始化
Java系列笔记(1) - Java 类加载与初始化 目录 类加载器 动态加载 链接 初始化 示例 类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理 ...
- java类的初始化
转载:http://blog.csdn.net/moreevan/article/details/6968718 我们知道一个类(class)要被使用必须经过装载,连接,初始化这样的过程.下面先对这三 ...
随机推荐
- node 进阶 | 通过node中如何捕获异常阐述express的特点
node如何捕获异常 node基于js的单线程,有了非阻塞异步回调的概念,但是在处理多个并发连接时,并发环境要求高,最重要的是单线程,单核CPU,一个进程crash则web服务都crash,但是为什么 ...
- MATLAB 与 Excel 接口
MATLAB 与 Excel 接口MATLAB 与 Excel 有两种接口方式:一种是通过 MATLAB 提供的 Excel 生成器,生成220 MATLAB 实用教程DLL 组件和 VBA 代码,实 ...
- python蟒蛇绘制
使用IDLE的文件方式编写代码并保存为PythonDraw.py文件 python蟒蛇绘制 import turtle引入了海龟绘图体系 使用setup函数,设定了一个宽650像素和高350像素的窗体 ...
- 3.Scala语法01 - 基础语法
- OOD 面向对象面试干货分享| 面向对象设计的SOLID原则
S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写. 简写 全拼 中文翻译 SRP The Single Res ...
- 并发编程(八)Lock锁
一.引言 线程并发的过程中,肯定会设计到一个变量共享的概念,那么我们在多线程运行过程中,怎么保证每个先拿获取的变量信息都是最新且有序的呢?这一篇我们来专门学习一下Lock锁. 我们先来了解几个概念: ...
- 从CPU缓存看缓存的套路
一.前言 不同存储技术的访问时间差异很大,从 计算机层次结构 可知,通常情况下,从高层往底层走,存储设备变得更慢.更便宜同时体积也会更大,CPU 和内存之间的速度存在着巨大的差异,此时就会想到计算机科 ...
- Apollo系列(二):Apollo在ASP.NET Core 3.1中使用
关于Apollo怎么安装,我就不介绍,可以看这篇文章:https://www.cnblogs.com/vic-tory/p/13736192.html 一.Apollo使用: 1.创建项目 2.添加配 ...
- Go-注释
什么是注释? 注释是给开发人员看的,目的是降低开发人员阅读代码的时间成本和代码阅读困难程度 Go-注释内容 1. 包注释,位于某个包下Go程序文件的顶部 2. 函数注释,位于Go函数的头部 3. 代码 ...
- QT博客:QT学习之路
http://www.qter.org/thread-629-1-1.html