How to initialize a constant object field for a class in java

Mohsen R. Aqdam :

I wonder what is the best way to initialize a constant field of complex object type for a class , which one has the most performance?

1) Inline initialization

public class TopClass {
   private static final ComplexObject sdf = new ComplexObject();
            
   public TopClass (
   }
}

2) Initializer methods

public class TopClass {
     private static final ComplexObject sdf = initializeComplexObject();
     private static ComplexObject initializeComplexObject(){
                return sdf == null ? new ComplexObject() : sdf;
     }
     public TopClass (
     }
}

3) Initialization in constructors , 4) Static initializer blocks or what other approach you suggest ...

Does the sdf initializes every time the new TopClass class is creating? I want sdf field only initialize once in the application lifetime.

Andy Turner :

Performance of static initializers almost doesn't matter (especially for such trivial initialization), since it is done just once for a class.

2) This specific method approach is redundant, because it is invoked immediately when the class is initialized; sdf is always null when the static initializer invokes that method, and you don't invoke that method again (at least, not for the purposes of giving sdf a different value). It's also pretty ropy because you are intentionally reading an uninitialized final field.

So, just remove the conditional, and you end up back with effectively the inline initializer approach, with the indirection of a method invocation.

The method approach would be useful if, say, you wanted to do other configuration on the formatter, for instance setting a time zone.

3) Don't initialize static members in a constructor. Constructors are for initializing instance members.

In particular, this requires you to make the static field non-final. This means that you then have to worry about visibility of updates to the field, in order to avoid multiple threads initializing the field because they see a null value

4) Initializing a field at its declaration is simply a shorthand for declaring a static initializer. The first code block in the question is semantically identical to this:

private static final ComplexObject sdf;

static {
  sdf = new ComplexObject(); 
}

There is no advantage in doing this explicitly, if you can get away with not.

Static initializers are sort-of like anonymous methods. Google's internal Java practices recommend using methods instead of explicit static initializer blocks where possible, in part because you can explicitly invoke them for tests, but also because they necessarily force you to initialize just one field. (I largely agree this is good advice, but note that you lose definite assignment checking in methods - as demonstrated above - which can help to catch certain types of bug).

In conclusion: use private static final ComplexObject sdf = new ComplexObject();, because you don't need anything more complicated.


The far bigger problem here is correctness, namely ensuring that sdf is not shared between threads: before you edited the question, sdf was a SimpleDateFormat, which is not thread-safe. I have no idea what ComplexObject is, but you need to ensure either that it is thread-safe, or that it is accessed in a thread-safe way. Worry about things like that before micro-optimizations.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325297&siteId=1