8

I originally thought that static blocks were for static variables but the compiler allows both A and B to compile and run, what gives?
A

   private static final Map<String,String> m = new HashMap<String,String>();

        {
            m.put("why", "does");
            m.put("this","work");
        }

B

 private static final Map<String,String> m = new HashMap<String,String>();

        static{
               m.put("why", "does");
               m.put("this","work");
             }

Running System.out.println(Main.m.toString()); for A prints

{}

but running the same for B prints out in Yoda-speak

{this=work, why=does}

non sequitor
  • 18,296
  • 9
  • 45
  • 64

2 Answers2

13

The non static block is executed when an "instance" of the class is created.

Thus

System.out.println(Main.m.toString());

prints nothing because you haven't created an instance.

Try creating an instance first

 Main main = new Main();

and you'll see the same message as B

As you know class variables (declared using static) are in scope when using instance blocks.

See also:

Anonymous Code Blocks In Java

Community
  • 1
  • 1
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
6

In A, you have an instance initializer. It will be executed each time you construct a new instance of A.

If multiple threads are constructing A instances, this code would break. And even in a single thread, you normally don't want a single instance to modify state that is shared by every instance. But if you did, this is one way to achieve it.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • 1
    Erickson is correct - create a new instance, and they will be equivalent. And if you change the values for those keys around, and then create another new instance, they will be replaced with the original values again. – aperkins Oct 15 '09 at 20:45