views:

160

answers:

5
public class Code{

//many properties
//...

final String NEWLINE;// ohh a final property!

void creation() //this method is for avoid repetition of code
{        

    //final initialization can't be put here =(

    Source= new StringBuffer();

   //many other commons new's ..
   //...
}

Code()
{
    NEWLINE = System.getProperty("line.separator");
    creation();
}

Code(String name, int numberr)
{
    NEWLINE = System.getProperty("line.separator");
    creation();

    name=new Someting(name);
    number = new Magic(number);
}

}

+3  A: 

Just do:

final String NEWLINE = System.getProperty("line.separator");

See: JLS 8.3.2. Initialization of Fields.

See also: JLS 12.5 Creation of New Class Instances for execution order.

polygenelubricants
When would be that line executed? at creation of first object automatically?
Hernán Eche
This field should be static anyway, but that's beside the point.
Michael Myers
+1  A: 

If they are being initialized the same way every time, you can put the code outside of the constructors. Java allows you to do:

final String NEWLINE = System.getProperty("line.separator");

You can also have all constructors other than the no-argument one call the no-argument constructor. For example:

Code(String name, int number)
{
    this();

    name=new Someting(name);
    number = new Magic(number);
}
Justin Ardini
+5  A: 

All initializers are added by the compiler to the beginning of each constructor. This includes:

  • instance variable initialization
  • initialization blocks { .. }

So you don't have to include this everywhere just place it either as an instance-variable initialization:

private final String NEWLINE = System.getProperty("line.separator");

or in initialization block:

{
     NEWLINE = System.getProperty("line.separator");
}

Of course, in this precise example, you should make the field static.

Bozho
+6  A: 

Here is your code with 4 different ways of initializing final variables.

  1. inline
  2. anonymous initializer block
  3. initialized in the constructor
  4. calling the default constructor explicitly

The resulting output is shown below.

public class Code {

    // many properties
    private String name;
    private String number;
    // ...

    // 1.
    final String NEWLINE_1 = "1" + System.getProperty("line.separator");
    final String NEWLINE_2;
    final String NEWLINE_3;

    // 2.
    {
        System.out.println("initializer block invoked before Constructor");

        NEWLINE_2 = "2" + System.getProperty("line.separator");
        // final initialization CAN be put here =(

        // Source = new StringBuffer();

        // many other commons new's ..
        // ...
    }

    Code() {
        System.out.println("default constructor");
        // NEWLINE_1 = "error";     can't do this
        // NEWLINE_2 = "error";     can't do this

        // 3.
        NEWLINE_3 = "3" + System.getProperty("line.separator");
    }

    Code(String name, int number) {
        // 4.
        this();
        System.out.println("constructor(name, number)");

        name = new String("Someting(name)");
        this.number = new String("Magic(number)");
    }

    public static void main(String[] args) {
        Code code_1 = new Code();
        System.out.println(code_1.NEWLINE_1 + ":" + code_1.NEWLINE_2 + ":" + code_1.NEWLINE_3);

        Code code_2 = new Code("crowne", 2);
        System.out.println(code_2.NEWLINE_1 + ":" + code_2.NEWLINE_2 + ":" + code_2.NEWLINE_3);
    }
}

initializer block invoked before Constructor
default constructor
1
:2
:3

initializer block invoked before Constructor
default constructor
constructor(name, number)
1
:2
:3
crowne
+1  A: 

One more, if the initialization is complex and you must do it during construction, provide a static method the returns the result, as in:

Code()
{
    NEWLINE = newLineValue();
    creation();
}

Code(String name, int number)
{
    NEWLINE = newLineValue();
    creation();

    name = new Something(name);
    number = new Magic(number);
}

private static String newLineValue()
{
    return System.getProperty("line.separator");
}

In this case, newLineValue() is trivial so I wouldn't use it here, but if this actually had a significant amount of work then it could be useful. You can also pass in parameters from the constructor.

Kevin Brock