Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning in a static initializer

This isn't valid code:

public class MyClass
{
    private static boolean yesNo = false;

    static
    {
        if (yesNo)
        {
            System.out.println("Yes");
            return; // The return statement is the problem
        }
        System.exit(0);
    }
}

This is a stupid example, but in a static class constructor we can't return;. Why? Are there good reasons for this? Does someone know something more about this?

So the reason why I should do return is to end constructing there.

Thanks

like image 293
Martijn Courteaux Avatar asked Apr 09 '10 11:04

Martijn Courteaux


People also ask

How do you use a static initializer?

However, the static initialization blocks can only initialize the static instance variables. These blocks are only executed once when the class is loaded. There can be multiple static initialization blocks in a class that is called in the order they appear in the program.

What is static initializer?

A Static Initialization Block in Java is a block that runs before the main( ) method in Java. Java does not care if this block is written after the main( ) method or before the main( ) method, it will be executed before the main method( ) regardless.

How many times is the static initializer block executed?

2. Static Block. Static initializer block or static initialization block, or static clause are some other names for the static block. Static block code executes only once during the class loading.

Is Java static initializer thread safe?

Yes, Java static initializers are thread safe (use your first option). However, if you want to ensure that the code is executed exactly once you need to make sure that the class is only loaded by a single class-loader. Static initialization is performed once per class-loader.


4 Answers

I think the reason is that initializers are carried together with field initializations (and with constructors, in the case of instance initializers). In other words, the JVM only recognizes one place to initialize static fields, and thus all initializations - whether in blocks or not - must be done there.

So, for example, when you write a class:

class A {
    static int x = 3;
    static {
        y = x * x;
    }
    static int z = x * x;
}

Then it's actually as if you've written:

class A {
    static int x, y, z;
    static {
        x = 3;
        y = x * x;
        z = x * x;
    }
}

This is confirmed if you look at the disassembly:

static {};
  Code:
   0:   iconst_3
   1:   putstatic       #5; //Field x:I
   4:   getstatic       #5; //Field x:I
   7:   getstatic       #5; //Field x:I
   10:  imul
   11:  putstatic       #3; //Field y:I
   14:  getstatic       #5; //Field x:I
   17:  getstatic       #5; //Field x:I
   20:  imul
   21:  putstatic       #6; //Field z:I
   24:  return

So if you would have added a "return" somewhere in the middle of your static initializer it would also have prevented z from being calculated.

like image 151
Oak Avatar answered Oct 18 '22 22:10

Oak


  • the program flow can always be structured to go without the need for return. (In your example putting System.exit(0) in an else clause would achieve the desired result)

  • in you really need it, you can move the code in a static method and call it from the initializer:

.

static {
    staticInit();
}

private static void staticInit() {
    if (yesNo) {
        System.out.println("Yes");
        return;
    }
    System.exit(0);
}

Note that this is not a static constructor, it's a static initializer. Nothing gets constructed.

like image 11
Bozho Avatar answered Oct 18 '22 23:10

Bozho


From JSL regarding static initializers:

"It is a compile-time error for a static initializer to be able to complete abruptly (§14.1, §15.6) with a checked exception (§11.2). It is a compile-time error if a static initializer cannot complete normally (§14.21)."

Abrupt completion (among others): "return with no value", "return with a given value", etc.

So a return statement in a static initializer is an "abrupt completion" and produces a compile-time error.

like image 2
jalopaba Avatar answered Oct 18 '22 22:10

jalopaba


What should you return to? In a static initializer there is no caller, so a return doesn't make sense as far as I see it. Static initializers are executed when the class is loaded for the first time.

like image 1
Eric Eijkelenboom Avatar answered Oct 18 '22 22:10

Eric Eijkelenboom