• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Question on class loading

 
aditya chaudhari
Ranch Hand
Posts: 31
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All ,
I have question on class loading when we extend class and when we just use object of class without extending it.

Code 1 :



code 2 :


As per i know class is loaded when we use its object.
Also what exactly happens when we extend class that it gets loaded ( as it prints static block) and not when we use B b =null;...?/

Please tell me where i am going wrong what are rules for class loading.?
 
Sergei Zhylinski
Ranch Hand
Posts: 84
1
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Your class 'B' is never initialized because it is not used.

"A class of interface of type 'T' will be initialized immediately before the first occurrence of any of the following:

* 'T' is a class and an instance of 'T' is created;
* 'T' is a class and 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 it is not a constant;
* 'T' is a top-level class, and assert statement lexically nested within 'T' is executed." (JLS, p. 317)

I would also suggest to pay attention to the following sample:



The output:

ii=2
iii=5
2
j=3
jj=4
3
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
aditya chaudhari wrote:As per i know class is loaded when we use its object.
Also what exactly happens when we extend class that it gets loaded ( as it prints static block) and not when we use B b =null;...?/

In code 1: to run the main method, the Test class must be loaded. In order to load the Test class, its parent classes must be loaded as well and that's why the print statement in the static initializer block is executed.

In code 2: you are not using class B, you just declared a reference variable of type B. If you changed the line to B b = new B();, the print statement in the static initializer block will be executed.

Nice to know: using the VM argument -verbose:class (when you run your application) you get information about each class loaded.

Hope it helps!
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sergei Zhylinski wrote:I would also suggest to pay attention to the following sample:

Let's have some fun with your great example Will the output be the same if we use class or instance variables instead of the interface constants?

class variables


instance variables
 
aditya chaudhari
Ranch Hand
Posts: 31
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Roel and Sergei ,

Thank you for your insights.

All codes mentioned by you really very usefull.

I am still playing with that codes and concepts , for time being my question mentioned is resolved.
Ofcource while playing around with code i 'll surly post if any problem i come across.

Roel thank you for additional "Nice to know:" tip it will use this in my future projects to know who all are using memory.


 
Mushfiq Mammadov
Ranch Hand
Posts: 187
25
Java jQuery Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote: Will the output be the same if we use class or instance variables instead of the interface constants?

class variables

It is unclear that why j and jj don't initialize when we call J.ii

Another question: if we call J.ii, ii initialize and iii too and prints the value of ii. But we call J.i, ii and iii don't initialize, only prints the value of i. I can't understand it, it is unclear too.
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mushfiq Mammadov wrote:It is unclear that why j and jj don't initialize when we call J.ii

You'll find the explanation of a similar case in JLS section 12.4.1. When Initialization Occurs and more specific in Example 12.4.1-2. Only The Class That Declares static Field Is Initialized.

The explanation applied to this example: The class J is never initialized; the reference to J.ii is a reference to a field actually declared in class I and does not trigger initialization of the class J.

Just for completeness. If you run the application with the VM argument -verbose:class you get information about each class loaded. For this code both classes I and J are loaded (only showing the appropriate classes):
[Loaded ClassVariables from file:...]
[Loaded I from file:...]
[Loaded J from file:...]
[Loaded Test3 from file:...]
ii=2
iii=5
2

So although class J is loaded, the class is not initialized (for the aforementioned reason) and thus no static variables are initialized.

Mushfiq Mammadov wrote:Another question: if we call J.ii, ii initialize and iii too and prints the value of ii. But we call J.i, ii and iii don't initialize, only prints the value of i. I can't understand it, it is unclear too.

I can't reproduce this with the code snippet of the ClassVariables class. I only have the exact same output if I.i is a compile-time constant (by adding the final keyword (or if I use the example with the interfaces). So with this declaration of I.ionly the value of I.i is printed. If you run the application again with the VM argument -verbose:class you'll see classes I and J are not loaded at all (only showing the appropriate classes):
[Loaded ClassVariables from file:...]
1

Which makes sense if you have a look at the decompiled codeSo because I.i is a compile-time constant, the Java compiler performs an optimization and replace the variable with its actual value, therefore no other classes have to be loaded.

Hope it helps!
Kind regards,
Roel

(Disclaimer: this is pretty advanced stuff, I would be surprized if you get a similar question on the OCA exam)
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I misread Mushfiq's post and thought he had some doubts about the code snippet with the interfaces. So I was already typing a reply and when I almost was finished, I discovered my mistake. Instead of GC'ing my reply, I'll just post it here as well. Maybe it's helpful for some other ranchers So in this post it's all about this code snippet

Mushfiq Mammadov wrote:It is unclear that why j and jj don't initialize when we call J.ii

You'll find the explanation of a similar case in JLS section 12.4.1. When Initialization Occurs and more specific in Example 12.4.1-3. Interface Initialization Does Not Initialize Superinterfaces. The explanation applied to this example: The reference to J.ii is a reference to a field actually declared in interface I that is not a constant variable; this causes initialization of the fields of interface I, but not those of interface J.

Just for completeness. If you run the program using the VM argument -verbose:class (when you run your application) you get information about each class/interface loaded. For this code both interfaces I and J are loaded (only showing the appropriate classes/interfaces):
[Loaded InterfaceVariables from file:...]
[Loaded I from file:...]
[Loaded J from file:...]
[Loaded Test3 from file:...]
ii=2
iii=5
2

So although interface J is loaded, the interface fields are not initialized (for the aforementioned reason).

Mushfiq Mammadov wrote:Another question: if we call J.ii, ii initialize and iii too and prints the value of ii. But we call J.i, ii and iii don't initialize, only prints the value of i. I can't understand it, it is unclear too.

That's also explained in the same example of the same JLS section The explanation applied to your example: The reference to J.i is to a field that is a constant variable; therefore, it does not cause I to be initialized.

If you run the application again with the VM argument -verbose:class you'll see interfaces I and J are not loaded at all (only showing the appropriate classes/interfaces):
[Loaded InterfaceVariables from file:...]
1

Which makes sense if you have a look at the decompiled codeSo because I.i is a compile-time constant, the Java compiler performs an optimization and replace the variable with its actual value, therefore no other interfaces have to be loaded.

Hope it helps!
Kind regards,
Roel

(Disclaimer: this is pretty advanced stuff, I would be surprized if you get a similar question on the OCA exam)
 
Mushfiq Mammadov
Ranch Hand
Posts: 187
25
Java jQuery Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:I misread Mushfiq's post and thought he had some doubts about the code snippet with the interfaces. So I was already typing a reply and when I almost was finished, I discovered my mistake. Instead of GC'ing my reply, I'll just post it here as well. Maybe it's helpful for some other ranchers

Both of two posts are very helful. Your labour is undeniable for this forum, thanks a lot
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic