JAVA's methods for creating and destroying objects

  • 2020-06-03 06:34:36
  • OfStack

There are several ways to create objects

The constructor Static factory method Through Builder

Advantages of the static factory approach

Have a name - the call is clearer No new object is created per call An object of any subtype of the original return type can be returned When creating instances of parameterized types, make the code cleaner

Disadvantages of the static factory approach

A class cannot be subclassed if it does not contain a Shared or protected constructor It is virtually indistinguishable from any other static method

Consider using a builder when you encounter multiple constructor parameters

Overlapped constructor pattern

However, with many parameters, the client code is difficult to write and difficult to read.

JavaBeans mode.

A parameter-free constructor is called to create the object and the setter method is called to set the parameters.

Disadvantages: The construction process is split into several calls, resulting in the possibility of being in a different state.

Builder mode

Have the client call the constructor/static factory with all the necessary parameters to get the builder object, then call methods like setter, and finally call the unreferenced build method to generate the immutable object.


public class NutritionFacts { 
  private final int servingSize; 
  private final int servings; 
  private final int calories; 
  private final int fat; 
  private final int sodium; 
  private final int carbohydrate; 
 
  public static class Builder { 
    //Required parameters 
    private final int servingSize; 
    private final int servings; 
 
    //Optional parameters - initialized to default values 
    private int calories   = 0; 
    private int fat     = 0; 
    private int carbohydrate = 0; 
    private int sodium    = 0; 
 
 
    public Builder(int servingSize, int servings) { 
      this.servingSize = servingSize; 
      this.servings = servings; 
    } 
 
    public Builder calories(int val){ 
      calories = val; return this; 
    } 
    public Builder fat(int val){ 
      fat = val; return this; 
    } 
    public Builder carbohydrate(int val){ 
      carbohydrate = val; return this; 
    } 
    public Builder sodium(int val){ 
      sodium = val; return this; 
    } 
 
    public NutritionFacts build(){ 
      return new NutritionFacts(this); 
    } 
  } 
 
  private NutritionFacts(Builder builder) { 
    servings   = builder.servings; 
    servingSize = builder.servingSize; 
    calories   = builder.calories; 
    fat     = builder.fat; 
    sodium    = builder.sodium; 
    carbohydrate = builder.carbohydrate; 
  } 
} 
 
//Client 
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). 
  calories(100).sodium(35).carbohydrate(27).build(); 

builder can verify constraints and can have multiple variable parameters.

But the Builder pattern is more verbose, with only a few parameters ( > =4).

Reinforce the Singleton attribute with a private constructor or enumeration type

Single-element enumerated types have become the best way to implement Singleton.


public enum Elvis { 
  INSTANCE; 
 
  public void leaveTheBuilding() {...} 
} 

This approach provides a serialization mechanism and prevents multiple instantiations.

The ability to not instantiate is enhanced with private constructors

To not be instantiated, use a private constructor.


//Noninstantiable utility class 
public class UtilityClass { 
  private UtilityClass() { 
    throw new AssertionError(); 
  } 
 
  ... // Remainder omitted 
} 

This way, a class cannot be subclassed.

All constructors must explicitly or implicitly call superclass constructors, in which case subclasses have no accessible superclass constructor calls.

Avoid creating unnecessary objects

Reuse immutable objects, mutable objects that are known not to be modified.

For immutable classes that provide both static factory methods and constructors, you can often use static factory methods to avoid creating unnecessary objects. Each time the constructor is called, a new object is created.

Auto-boxing (autoboxing) creates new methods for creating redundant objects. Use base types first over boxing base types.

Eliminates expired object calls

As long as the class manages its own memory, it should be aware of memory leaks. Once the element is released, any object references contained in the element should be cleared.

Other common memory leaks are caches, listeners, and other callbacks.

The best way to ensure that callbacks are immediately garbage collected is to save only their weak references.

Avoid finalization methods

The disadvantage of finalization is that there is no guarantee that it will be executed in a timely manner.

You should not rely on finalization methods to update significant persistent state.

Explicit termination methods are usually used in conjunction with the try-finally structure to ensure timely termination.

The purpose of the termination method

When the object owner forgets to call an explicit termination method, the termination method ACTS as a safety net. If the termination method finds that the resource has not been terminated, a warning is logged. Terminates non-critical local resources.

Remember to call super.finalize if the finalization method is used.


Related articles: