• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

static initializer setting parent variable

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Output of Test:
A='A' B='B' C='C'

Now comment in method printAbc in class DEF, and the output becomes:
A='D' B='E' C='F'

Why? I would have expected the second behavior in both cases? Why is the static initializer in DEF failing to modify the static variables in ABC as used by a static method in ABC?

Thanks
 
Master Rancher
Posts: 4806
72
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is because JLS 12.4.1 defines exactly when class initialization occurs. The relevant part here is:

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 a static method declared by T is invoked.


Since the static method printAbc() is declared in class ABC, the spec requires that ABC be initialized. It does not require (or allow) that DEF be initialized - unless you uncomment the printAbc() in DEF, in which case it becomes a method declared in DEF.
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Member variables and static methods are not runtime polymorphic. I think this means that when we invoke DEF.printAbc(), the runtime does not have to fully initialize class DEF, since it can determine that ABC's method will be called, so DEF's static initializer doesn't get run.
 
Jack War
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Mike/Jeff, I tested this by adding a static method to DEF that did nothing. And the behavior was correct, i.e. DEF was printed. It's counter-intuitive that DEF.someFunctionInSuperClass does not fully instantiate DEF.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome!

Jack War wrote:It's counter-intuitive that DEF.someFunctionInSuperClass does not fully instantiate DEF.



Terminology nitpick: You're not instantiating ABC or DEF at all. That would only happen if, for instance, you did new ABC(). Instantiating means creating an object that is an instance of that class. What we're talking about here is initializing the class, which is a part of the class loading process that prepares the class for use.
 
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Try Class.forName("DEF") and see whether that makes any difference, but I suspect it won’t. It might be that DEF is only loaded if you use it.

There is an explanation about hiding, shadowing, obscuring, etc., in Java Puzzlers by Joshua Bloch and Neal Gafter.
 
Mike Simmons
Master Rancher
Posts: 4806
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Try Class.forName("DEF") and see whether that makes any difference, but I suspect it won’t. It might be that DEF is only loaded if you use it.


This is covered in the API for java.lang.Class and the forName() method. Compare forName(String) to forName(String, boolean, ClassLoader) as well.
 
reply
    Bookmark Topic Watch Topic
  • New Topic