0

According to my knowledge whenever a class gets loaded an object of Class.class gets created for it by JVM, which stores all meta information of the loaded class.

When we use forName("classname") method, it first loads "classname" and then creates Class.class object for it and returns reference to the created Class.class object.

Example.java is given as:

class Example
{
        static
        {
                System.out.println("Example Loaded");
        }
        Example()
        {
                System.out.println("Example Constructed");
        }
}

Use.java is:

import java.lang.reflect.*;
class Use
{
        int i;
        public static void main(String[] args) throws Exception
        {
                Class c = Class.forName("Example");
                Constructor[] con = c.getDeclaredConstructors();
                for(Constructor x: con)
                {
                        System.out.println(x.getName());
                }
        }
}

Running Use.java outputs:

Example Loaded
Example

getClass() is a method which can be used only with objects. So definitely before object creation a class will be loaded and object of Class.class will be created for it.

According to "Class and Data" section of http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html, "Whenever we compile any Java file, the compiler will embed a public, static, final field named class, of the type java.lang.Class, in the emitted byte code". We can use this field as:

import java.lang.reflect.*;
class Use
{
        int i;
        public static void main(String[] args) throws Exception
        {
                Class c = Example.class;
                Constructor[] con = c.getDeclaredConstructors();
                for(Constructor x: con)
                {
                        System.out.println("Hello "+x.getName());
                }
        }
}

Output of above code is:

Hello Example

Static body of Example not get executed. Means the class Example did not get loaded.

My doubt is:

If class did not get loaded then object of Class.class also not get created for it. Then from where the statement "Class c = Example.class" returning the reference to Class.class?

my name is GYAN
  • 1,269
  • 13
  • 27

2 Answers2

1

There is a difference between class loading and class initialization. A class can be loaded but not initialized. This is happening in case -2.

static initializers of a class are run when the class gets initialized and not when the class gets loaded.

Class.forName(String className) both loads and initializes the class. Hence in case 1, Example Loaded will be printed.

In case -2, since you are not doing anything to trigger the class initialization, Example Loaded will not be printed.

Also try Class c = Class.forName("Example", false, Sample.class.getClassLoader()); version of forName (which only loads the class but doesn't initialize it)and see what happens.

Just try to access a static field in class 2 (same code) and see what will happen.

class Example
{
    static int i= 5;
        static
        {
                System.out.println("Example Loaded");
        }
        Example()
        {
                System.out.println("Example Constructed");
        }
}

public static void main(String[] args) {
    Class c = Example.class;
    Constructor[] con = c.getDeclaredConstructors();
    for(Constructor x: con)
    {
            System.out.println("Hello "+x.getName());

    }
    System.out.println(Example.i);

}

Also you can check which classes are loaded but not initialized using java -verbose:class option.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • That means Class.class object for class Example can be created even if it is not initialized. Field "class" will be loaded in Method area with other Example class information. From Method Area JVM is picking the "class" reference to Class.class object for Example. Am I correct? – my name is GYAN Apr 26 '16 at 09:34
  • 1
    @mynameisGYAN - Yes. Class Objects are created in the JVM as classes are loaded. – TheLostMind Apr 26 '16 at 09:37
  • @mynameisGYAN - Use `javap -v Example.class` and check `#1 ` under *constant pool* :) – TheLostMind Apr 26 '16 at 09:56
1

As TheLostMind said "there is difference between class loading and class initialization. static initializers of a class are run when the class gets initialized and not when the class gets loaded".

Static members gets loaded in method area and so the field named "class".

But a class does not gets initialized for accessing a "static final" variable.

Example.java

class Example
{
        static final int i = 5;
        static
        {
                System.out.println("Example Loaded");
        }
        Example()
        {
                System.out.println("Example Constructed");
        }
}

Use.java

import java.lang.reflect.*;
class Use
{
        public static void main(String[] args) throws Exception
        {
                System.out.println(Example.i);
        }
}

Running Use.class results

5

But if Example.i was

static int i = 5;

then running Use.class results as:

Example Loaded
5

Similar thing happens with field "class". As TheLostMind told "Class Objects are created in the JVM as classes are loaded". Field "class" initialized by compiler to point to object Class at compile time. So accessing Example.class we can access the class object. But accessing the field "class" does not make the class initialized, because this field is static and final.

my name is GYAN
  • 1,269
  • 13
  • 27