2

I have learned that in a class you can declare variables and methods. They can both be declared as static if that is prefered.

Now I have encountered a program example I do not really understand. After some variable declaration in the class there is a field declared as static and inside there is program code.

When is this code executed? My guess is that the code is executed like following when a new object is created:

  1. Memory allocation for the instance variables.
  2. Execution of the contructors connected to the instance variables.
  3. Exection of the static field
  4. Execution of the constructor (if "= new Constructor() is used when the object is created)

If I execute

MyCars myCars = new MyCars();

the following will happen in this order?

public class MyCars
{
    private Car volvo = new Car()
 //              (1)       (2)
    static
    {
        volvo.setNumberOfWheels = 4;
 //                  (3)
    }

    public MyCars()
    {
         volvo.setBrand = "Volvo";
         volvo.setModel = "XC70";
                 (4)
    }

Here is the original code:

public class SettingsSetter extends ListActivity
{
    private static Map<Integer,String> menuActivities=new HashMap<Integer,String>();
    private static List<BooleanSetting> settings=new ArrayList<BooleanSetting>();

    static 
    {
        menuActivities.put(R.id.app,
            Settings.ACTION_APPLICATION_SETTINGS);
        menuActivities.put(R.id.security, Settings.ACTION_SECURITY_SETTINGS);
        menuActivities.put(R.id.wireless,
            Settings.ACTION_WIRELESS_SETTINGS);
        menuActivities.put(R.id.all,
            Settings.ACTION_SETTINGS);

        settings.add(new BooleanSetting(Settings.System.INSTALL_NON_MARKET_APPS,
            "Allow non-Market app installs", true));
        settings.add(new BooleanSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED,
            "Use haptic feedback", false));
        settings.add(new BooleanSetting(Settings.System.ACCELEROMETER_ROTATION,
            "Rotate based on accelerometer", false));
    }
2
  • Is your example supposed to make volvo static like your real code? Commented Jan 3, 2012 at 9:01
  • I think you meant for volvo to be static. Commented Jan 3, 2012 at 9:03

3 Answers 3

5

Static initialisers are executed when the class is loaded, so before any instances are created. Your first code is in error, since volvo is an instance (non-static) variable, and the static block cannot access it. Revisiting your example:

public class MyCars
{
    private static Car audi = new Car()
 //                     (2)
    private Car volvo = new Car()
 //              (5)       (6)
    static
    {
        audi.setNumberOfWheels = 4;
 //                  (3)
    }
    public MyCars()
    {
         volvo.setBrand = "Volvo";
         volvo.setModel = "XC70";
 //              (7)
    }
}

MyCars myCars = new MyCars();
// (1)                (4)
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you @Amadan (and all other). Now it's more clear to me. Is this correct: Your number 1 is load class and number 4 is instance creation? If I write MyCars myCars; MyCars myNeighboursCars; Will the class be loaded twice?
No, a class is only loaded once - and thus, static blocks and initialisers are only executed once.
Interesting this. Are the class loaded at first use (1 above) or are all the classes in the project loaded directly before main is executed?
AFAIK, first use. Test for yourself: class A { static { System.out.println("A"); } } and then class B { public static void main(String[] args) { A a; System.out.println("B"); a = new A(); } } - the output is "B" then "A", so the class is loaded just before the first object of A is constructed (not declared, not at start of the program). You can also load it manually (for example, using Class.forName("B")) - by which you can force class load to happen earlier than the default class loader would make it.
I tried that out and it works as you tell me. With that in mind, shouldn't the answer above be revised. At 1 we only reserve memory for a pointer (that later will be pointing to the object "new MyCars()"). 4 -> 2, 2 -> 3, 3 -> 4.
|
0

That's not a field, it's a static initializer. It will be executed once when the class is first loaded. It will not be executed when an instance of the class is initialized.

BTW, your MyCars code will not compile because a static initializer cannot refer to instance variables, as it will be executed before there are any instances of the class.

Comments

0

It is a static block, ora a static initialization block, that is executed when the class is loaded into the JVM. Whatever you have inside, it will be automatically executed at load time.

It is also possible to have multiple static blocks inside the same class, the JVM garauntees you that they will be executed in the order they appear.

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.