开发者

Are instance initializers considered bad style?

I personally quite like instance initializers - I use them to assign default values to things such as collections so when writing constructors I don't have to remember to assign them the same default values each time. It seems quite elegant to me - avoids annoying NPE's popping up and avoids duplicate code. A private method doesn't seem as nice because a) it can't assign values to final fields, b) it could be run elsewhere in code and c) the method still needs to be explicitly called at the start of each constructor.

However, the flip side with others I have spoken to is that they're confusing, some people reading the code might not understand what they do or when they're called and thus they could cause more problems than they sol开发者_StackOverflow社区ve.

Are proper use of these initializers something to be encouraged or avoided? Or is it an "each to their own" case?


It depends, for instance on the level of knowledge about Java readers of your code can be expected to have, and whether the alternatives are practical.

Alternatives are:

  • inline into every constructor. If there are several constructors, this violates DRY.
  • have all constructor delegate to the same constructor, and put the code in that one. If the constructors are non-trivial, and take different arguments, this might require to write a new constructor that receives the values of all fields in its arguments. If there are many fields, this can get rather lengthy (and hard to read, since it is not obvious which value is being assigned to which field)
  • have all constructors invoke an init method. Can't assign final fields that way. Should probably prevent the method from being overridden. Might want to prevent it from being called several times.

Since initializers are uncommon, you should only prefer them when there is a clear advantage to using them. My most recent use of one was:

private final Collator collator = Collator.getInstance();
{
    collator.setStrength(Collator.SECONDARY);
}

in a class with several constructors with rather different argument lists and half a dozen other fields.


I don't really use them but one case I can see them useful is when you have multiple constructors, not calling themselves (this(..)), that need some common initialization logic shared, and no need to create a specific private method for that. Oh and the only place I use instance initializers are for quickly initialize in one-line Maps for instance, eg:

Map<String,String> m = new HashMap<String,String>(){{
   put("a","b");
   put("c","b");
   put("d","b");
}};

Could be useful to initialize a map in let's say an interface

interface  A {

   Map<String,String> PROPS = Collections.unmodifiableMap(new HashMap<String,String>(){{
      put("a","b");
      put("c","b");
      put("d","b");
   }});
}

Still doing so you end up with a annonymous subclass of HashMap...


It is better to overload your constructor and have as many constructor variations as you like. The best example is Java's Arraylist. It has two constructors. One that takes a integer as an argument and other being a default constructor. If you take a look at the default constructor, it infact calls the Single argument constructor with a constant value 10.

List<Object> x = new ArrayList<Object>(); //Creates with default capacity 10
List<Object> y = new ArrayList<Object>(40); //Creates with the specified capacity 40


I would stay they are preferred. But based on the other responses it appears it might be more "to each his own". I like them because it keeps the related information together. Rather than declaring a value and setting it in the constructor, you can do it all in one place.


You can use a constructor with parameters and this constructor calls the private setters. And than implement a default constructor who calls that contructor with default values. If you want assign default values to properties, do it in the declaration.

The instance and static initializers are good to init complex datastructures like matrices or cubes.

By the way, a final property is mostly called a constant.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜