1

I have two classes in two different files, each one has a static variable, I would like to know if there is a way to predict which one will be initialized first (is it implementation dependant)? My code looks like this?

File1:
public class A
{
  public static boolean a = Logger.log();
}

File2:
public class B
{
  public static boolean b = Logger.log();
}

File3:
public class Logger
{
  public static boolean log();
}
4
  • 3
    Show your complete relevant code, please. The way it's right now it won't compile. Ideally, post an SSCCE Commented Feb 18, 2013 at 12:27
  • 4
    To answer your question. It depends on which class is loaded first, and this depends on which class is used first. You have to look at the flow of code in the main method you're executing. Commented Feb 18, 2013 at 12:30
  • 4
    @jlordo - I would put this as an answer Commented Feb 18, 2013 at 12:32
  • If I'm not mistaken static variables are initialized at load time, not when the class is first used. If neither class is ever used will the log function not be called? Can I be sure that every time I run the code the log file will look the same? Commented Feb 18, 2013 at 12:35

3 Answers 3

10

It depends on when each class is first used.

From section 12.4.1 of the Java Language Specification:

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.

  • 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 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.

A reference to a static field (§8.3.1.1) causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

Section 12.4.2 of the JLS specifies the initialization procedure in detail.

To be honest, if your code requires one to be initialized before the other, despite having no obvious dependency, then you've got problems anyway.

Sign up to request clarification or add additional context in comments.

3 Comments

So in order to call log, I must use the class somewhere first? If all I want the class to do is to call log when the program loads, how do I do that?
@BenjyKessler: If you want to do something when the program loads, then put the logging calls within the flow control of the program startup - why would you want to use a static field initializer for that?
because I want to be able to add classes without changing the actual flow of the program, for instance if instead of calling log, I register the class in a factory, I don't want the factory to have to change every time a new type is added. I want to be able to add classes to the factory from outside the control flow.
0

According to your example - there is no way to init B.b before A.a because the access of B class will invoke static initialization of its supper class first.

If you really need to do A logic before B - try to encapsulation it in static methods:

public class A
{
  public static boolean a;
  public static init() {
   a = log();
  }
}

public class B
{
  public static boolean b;
  public static init() {
   b = log();
  }
}

public class Main
{
  public static void main(String[] args) {
   B.init();       
   A.init();      
  }
}

1 Comment

This is exactly what I want to avoid, I don't want the main to have to know which classes need logging.
0

JVM doesn't keep the record of all classes with it but when a class or the static member of class is requested, it loads the class from the memory. So the actual procedure that is followed is something like this:

When the class is requested very first time:

  1. All static Variables

  2. Static Blocks (by the order, first one first then second and so on)

  3. Instance Variables (Members)

  4. Initializer Blocks (by the order)

  5. Constructor

And the second or afterwards:

  1. All Instance Variables (Members)

  2. Initializer Blocks (by the Order)

  3. Constructor.

I hope this will help you.

Thanks...

Mr.777

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.