0

I am trying to understand the exact scenario when a class get loaded and initialized. I see the two articles below give different answers

javarevisited-A Class is initialized in Java whenan Instance of class is created using either new() keyword or using reflection using class.forName(), which may throw ClassNotFoundException in Java.

Java world-So when are classes loaded? There are exactly two cases: when the new bytecode is executed (for example, FooClass f = new FooClass();) and when the bytecodes make a static reference to a class (for example, System.out).

So when I create an instance of class using new keyword is class loaded or initialized?


Another thing to ask regarding loading due to reference variable:

javarevisited-Class loading is done by Class Loaders in Java which can be implemented to eagerly load a class as soon as another class references it or lazy load the class until a need of class initialization occurs

What does author mean by referencing here? Does he imply if A class have reference variable of B class then B class get loaded when its reference is encountered in A ??

But the author below says class NotUsed is not loaded but I see ClassInitializationTest class having its reference

javarevisited-

/** * Java class which is not used in this program, consequently not loaded by JVM */

class NotUsed {
 static { System.out.println("NotUsed Class is initialized "); }

}

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • From skimming through the articles the javaworld article is more simplistic and provides a high level overview and the javarevisited article goes more into details, so they not exactly contradict each other just talk about different things. As to your question about referencing, yes that's what it means. – Oleg Aug 09 '17 at 18:35

2 Answers2

1

You are confused by the javaworld article. Though it's a little harsh, for the purpose of this answer let's just say it's wrong and ignore it.

From the jvm specification

The Java Virtual Machine dynamically loads, links and initializes classes and interfaces. Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation. Linking is the process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed. Initialization of a class or interface consists of executing the class or interface initialization method

From the the highlighted text above you can see exactly what loading and initialization mean and that javaworld use loading (incorrectly) as a combined term for them.

From the jls

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.

From the javarevisited article:

NotUsed o = null;
..
class NotUsed {
    static { System.out.println("NotUsed Class is initialized"); }
}

Declaring a variable is not listed as one of the things that cause initialization so it's not initialized and "NotUsed Class is initialized" will not be printed. It is not defined by the specification if NotUsed will be loaded, using the default ClassLoader on sun's java 8 it will not be loaded.

Oleg
  • 6,124
  • 2
  • 23
  • 40
  • Thanks @Oleg. The author says "Class loading is done by Class Loaders in Java which can be implemented to eagerly load a class as soon as another class references it" but later in the comments above the NotUsed method you see "/** * Java class which is not used in this program, consequently not loaded by JVM */" But there is "NotUsed o = null;" reference statement in ClassInitializationTest class – Sreemanth Jasti Aug 09 '17 at 19:46
  • Just a quick example: Consider we are referencing class Fizz. Which statement causes the class to load. I am sure (2) causes Fizz class intilizing(after loading). But does statement (1) cause class loading? Fizz fizz = null;------------(1) fizz = new Fizz();----------(2). – Sreemanth Jasti Aug 09 '17 at 19:50
  • 1
    @SreemanthJasti What he means is that the specification doesn't define what to do and it can be implemented either way. I just checked in the standard java 8 and he is right it doesn't get loaded. You can play with it yourself based on [this answer](https://stackoverflow.com/a/482909/1398418). In your examples (1) nothing will happen but in theory it can be loaded but will never be initialized(jls forbids it). (2) In practice with the default classloader it will be loaded and initialized, in theory it could've already been loaded before. – Oleg Aug 09 '17 at 20:13
-1
myClass a = new myClass();

As I was taught, the first part is the initialisation, the second part after the "=" is the loading.

You can initialise a class:

myClass a;

Then load it later on in the code:

a = new myClass();

The same as variable initialisation.

  • This is not relevant he is asking about **Class** loading. As in what the classloader does. – Oleg Aug 09 '17 at 19:35