Java 필드 초기화

Posted by epicdev Archive : 2011. 10. 3. 15:27
출처: http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

Initializing Fields

As you have seen, you can often provide an initial value for a field in its declaration:
public class BedAndBreakfast {

    public static int capacity = 10;  //initialize to 10

    private boolean full = false;  //initialize to false
}
This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate. Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.

Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.


Static Initialization Blocks

static initialization block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. Here is an example:
static {

    // whatever code is needed for initialization goes here
}
A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

There is an alternative to static blocks — you can write a private static method:

class Whatever {
    public static varType myVar = initializeClassVariable();
	
    private static varType initializeClassVariable() {

        //initialization code goes here
    }
}
The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.
 

Initializing Instance Members

Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods.

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.

final method cannot be overridden in a subclass. This is discussed in the lesson on interfaces and inheritance. Here is an example of using a final method for initializing an instance variable:

class Whatever {
    private varType myVar = initializeInstanceVariable();
	
    protected final varType initializeInstanceVariable() {

        //initialization code goes here
    }
}
 
This is especially useful if subclasses might want to reuse the initialization method. The method is final because calling non-final methods during instance initialization can cause problems. Joshua Bloch describes this in more detail in Effective Java. 

출처: http://wahlstroem.org/bjorn/2008/07/24/instance-initializers-in-java/

At work I noticed an interesting piece of code. I wrote it in error, as I meant to write a static initializer (code that is run once when a static class is being referenced)


static {
// initialize static variables
}

but instead I wrote this


{
// initialize variables
}

It compiled nicely, but what is it good for?

The effect is not that of a static initializer, but it is actually run before the constructor; But not when referenced statically. You can have as many instance initializers as you want, and they are appearing to run in the order they are defined.

The author of “Java in a Nutshell” writes so nicely:

An instance initializer is simply a block of code inside curly braces that is embedded in a class definition, where a field or method definition normally appears.  A class (any class — not just anonymous classes) can have any number of instance initializers.  The instance initializers and any variable initializers that appear in field definitions for the class are executed in the order they appear in the Java source code.  These initializers are automatically run after the superclass constructor has returned but before the constructor, if any, of the current class runs.

This puzzles me, because this seems at first hand to be what we have constructors for. They are the blocks of code that is run whenever we instantiate a class, and should do all the complex logic and initialization that needs to be done to assure data integrity.

But; What about anonymous classes? You know, the ones that are used frequently in event-programming


someObject.addEventListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) { // .... }
});

They cannot have constructors, but I imagine it can be useful to have complex (more than one line..) initialization even there. Also, according to more seasoned programmers than my self, instance initializers can be used to make the code easier to read, since the initialization block can be placed right next to the variables.

The initializers are run in the order they are defined, and you can have as many you want. In contrast to constructors, which you can only have one of without an argument list. This could also be useful with regards to code readability, since complex constructors, like any block of code, should be avoided.

But beware, long-time maintenance could be troublesome if one isn’t careful. So-called “pretty”-tools often reorganize the code, e.g. alphabetically or by visibility. Since the instance initializers are run in the order they are defined, one has to make sure that they are not co-dependent. That would be a java-equivalent to Spaghetti Hell! 

'Archive' 카테고리의 다른 글

세부사항을 코드에서 몰아내라  (0) 2011.10.03
Camera의 setDisplayOrientation 메소드  (0) 2011.10.03
디미터 함수 법칙 (혹은 디미터 법칙)  (0) 2011.10.03
패키지의 순환적 의존성  (0) 2011.10.03
응답집합  (0) 2011.10.03