How to avoid code repetition initializing final properties?
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()
{
开发者_C百科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);
}
}
Here is your code with 4 different ways of initializing final variables.
- inline
- anonymous initializer block
- initialized in the constructor
- 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
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
.
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.
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);
}
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.
精彩评论