The existence of an interpreter is an implementation detail that is irrelevant for describing the behavior of a program. In principle, it is possible to have a JVM without an interpreter at all, as it could have only a compiler that translates all byte code to native code before executing, and still implement the correct behavior. Current desktop and server JVMs have both, executing the code in a mixed mode.
So, it is also irrelevant at which point blogs and videos mention the existence of an interpreter as a way to execute the code, the execution of code always implies the existence of technical means to execute the code, like an interpreter or compiler.
The actual behavior has been specified in The Java Language Specification, §12.4.1:
§12.4.1. When Initialization Occurs
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
T
is a class and an instance of T
is created.
- A
static
method declared by T
is invoked.
- A
static
field declared by T
is assigned.
- A
static
field declared by T
is used and the field is not a constant variable (§4.12.4).
T
is a top level class (§7.6) and an assert
statement (§14.10) lexically nested within T
(§8.1.3) is executed.¹
When a class is initialized, its superclasses are initialized (if they have not been previously initialized), as well as any superinterfaces (§8.1.5) that declare any default methods (§9.4.3) (if they have not been previously initialized). Initialization of an interface does not, of itself, cause initialization of any of its superinterfaces.
¹ this last bullet has been removed from newer specifications
Since the invocation of the main
method is an invocation of “a static
method declared by” your class, it implies the initialization of that class before the invocation. As you can derive from the last section, if the class containing the main
method has uninitialized superclasses, they are initialized even before that class.
For the standard Java launcher, the order of events is
- The main thread is created
- The main thread loads the specified application class
- The super classes of the application class are initialized, if not already initialized
- The application class is initialized
- The method
static void main(String[])
is invoked on the application class
The terms “application class” and “main class” are interchangeable.
Note that this list is only meant to bring these events into the right order. There are far more events happening behind the scenes. Obviously, for asking the application class loader to load the application class, given by name, the classes String
, Class
, and ClassLoader
must have been loaded and initialized, which also implies that their super class, Object
has been initialized even before that. The existence of the main thread implies the loading and initialization of the class Thread
. And all these classes use other classes behind the scenes.
You may run your application with the -verbose:class
option to see which classes are already loaded before your application class.