java接口初始化为什么生成clinit方法

在《深入理解java虚拟机》类初始化中有如下描述:
接口中不能使用静态语句块,但仍然有变量初始化的赋值操作,因此接口与类一样都会 生成<clinit>()方法。但接口与类不同的是,执行接口的<clinit>()方法不需要先执行 父接口的<clinit>()方法。只有当父接口中定义的变量使用时,父接口才会初始化。另外,接口的实现类在初始化时也一样不会执行接口的<clinit>()方法。

为什么我在如下实现时,并没有生成< clinit>??


public interface Util {
   int f=5;


}

javap -v Util.class
图片说明

接口中没有静态代码块,有变量,但是变量的修饰符是static final 已经在连接时指向ConstantValue,所以不会生成< clinit>
各位大佬,书上写的接口生成< clinit>是什么情况?

书上不是说变量的初始化,但是你用static final修饰,那么他就是常量了,不是变量
另外深究这些没用的东西干嘛,这个功能不能为你写新的功能提供任何帮助
喜欢研究底层的话,可以重点看逆向

时隔两年之后,我在阅读该书时也产生了同样的疑问。接口中不能存在静态语句块,不能声明静态变量,哪为什么还会创建clinit方法呢?原因是这样的:对于基本数据类型和字符串来说,在接口中声明的静态常量,在类加载的”准备“阶段,就完成了初始化,其值存储在常量池中。但是,对于其他引用数据类型,如java.util.Date,在接口中虽然是常量,确实在初始化阶段赋值的。因为在准备阶段其值并不在常量池中存在。

因为是常量,所以没有clinit。另外看了两遍这本书,真的是其义自见,受益匪浅。之前面试问我什么时候执行static代码块,答在Student student的时候,囧哈哈