20

I'm re-factoring some inherited code, but was stumped by the design decision and can't figure out the proper terms to google this. My predecessor would use blocks like this one:

public class ChildClass extends ParentClass {
    {
        inheritedVar = "someVal";
    }

    public ChildClass(){ /* constructor exists */ }
    // rest of code
}

What is the point of declaring a block of code with no keyword? It doesn't behave like a static block, I don't believe. Is it an alternative to setting in the constructor? Would this have some effect if a factory was being used (which in this case it's not)? I found a related thread here on this happening in C but the reasoning (scope & variable declaration) didn't seem relevant to Java.

Any thoughts or ideas on the "why" of this would be appreciated. It's easy enough to re-factor this, I'm just curious at this point.

Community
  • 1
  • 1
Riggy
  • 1,347
  • 1
  • 14
  • 26

4 Answers4

33

It is an initializer block. (Related to static initializer block) See Initializing Instance Members on this page:

http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

It is an alternative to a constructor. You could use it when providing multiple, overloaded constructors as a way to share code.

Personally, however, I find it much clearer to have the constructor call a named initializer method rather than rely on the anonymous code block. Although, the compiler does copy the initializer block to all constructors behind the scenes and you could argue that there is a performance increase similar to inline'ing a method declaration.

Mike
  • 8,853
  • 3
  • 35
  • 44
  • 2
    +1: I agree regarding the named initializer methods. However, given that there's only one constructor, the whole point of this block in my code base seems rather pointless. – Riggy Dec 14 '10 at 16:23
  • @Riggy, it certainly is redundant. – Mike Dec 14 '10 at 16:26
18

It's called an initializer block.

Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:

    {
        // whatever code is needed for initialization goes here
    }

The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • Both you and Mike left excellent answers, thank you both for the links. I hadn't thought about the multiple overloaded constructors, given that the various classes I've found only have one constructor each. – Riggy Dec 14 '10 at 16:22
  • One small nitpick - afaik the compiler does not copy the initializer block, it just adds a call from the constructor to the special method, which is what the { } becomes in the .class file. [Static initializer block becomes the method.] – Alex Miller Dec 14 '10 at 16:35
4

Your predecessor was still learning.

That's the best explanation you're likely to get. Perhaps at one point in time there was a need to have the code split up like this. It's hard to say. The code should certainly be written like this instead:

public class ChildClass extends ParentClass {
    public ChildClass() {
        inheritedVar = "someVal";
    }
    // rest of code
}

As for the initializer block, its purpose has been given by the other answers here. I threw my answer in as an attempt to answer the "why", which you requested. Unfortunately, for the real answer, you would have to ask your predecessor.

Erick Robertson
  • 32,125
  • 13
  • 69
  • 98
  • I had only posted the minimal amount of code to get my point across without burdening the SO readers with garbage code. I included the constructor only so that it would be apparent that a constructor exists in the code and that the nameless block wasn't replacing the constructor. Thanks! – Riggy Dec 14 '10 at 16:24
  • No problem. I removed the part of my answer asking about it. – Erick Robertson Dec 14 '10 at 16:28
  • 4
    You're right that it's not the best code. I'd suggest that the predecessor was learning. There are so many devs who call other devs idiots, and all it does is make people hide their mistakes so they don't get embarassed or worse, fired. I'd prefer to see "Your predecessor was still learning how to code well". I'm on a mission to make safe environments for devs to learn the right ways of doing things, and feel strongly that StackOverflow should be one of them - would you be willing to help, and change the language you use? – Lunivore Dec 14 '10 at 16:28
  • 1
    Yes, I am willing to do that here. I should not have assumed that the code was written by anyone who was supposed to know what they were doing. People are hired to learn as they go all the time. Of course, if I had a dime for every time I wrote some idiotic code... – Erick Robertson Dec 14 '10 at 16:33
  • For anyone of us, there is something we don't know. I'm not inclined to say does it make us all idiots, but if it does I most certainly wouldn't put it on a billboard. – Goran Jovic Dec 14 '10 at 16:36
-3

Scope. Any variables declared in the block go out of scope after the block. It's useful to keep variables scoped minimally.

Also, if you define an anonymous inner class, you use this syntax for the constructor.

gdj
  • 1,295
  • 10
  • 10