Access interface constants to explicitly trigger the execution of interface
initializers. The problem is that when we desugar default methods, the static
intializer of interface will not be executed. The JVM spec says that if an
interface has default methods, then when it is loaded, it will also be
initialized. After we desugar such an interface, its default methods are
removed, and when we load the interface, the <clinit> will not be executed.

This CL checks whether an interface has default methods and fields. If yes (needs to be initialized when the interface is loaded), it injects field access code
to access the interface fields in the <clinit> of the companion class.
We also create a constant $$CONSTANT$$ in the companion class.

Then for all the classes that implement the interface, we inject GETSTATIC in the class <clinit> to the $$CONSTANT$$ of the companion class of the interface. This indirection is to avoid the IllegalAccessError when the interface is package private.

Note that accessing an arbitrary interface field does not guarantee the
interface will be initialized. We need to access the field that is initialized
in the interface static initializer.

RELNOTES: None
PiperOrigin-RevId: 160414671
GitOrigin-RevId: 8740ca6bd0f4156aaf663c482bc3e9c7ebb2c556
Change-Id: I221d094c82d5bffa9b0a1f2082192b3211e70ea9
3 files changed
tree: c256bbcb844004c9b4a2fd373192bdf699f4bdc8
  1. java/