Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java constructor of "immutable class" with many fields with default values?

Tags:

I have a JAVA class with lots of fields. They should basically be set at the constructor phase and never change. Semantically the class then is an immutable one.

public class A{     final int a;     final short b;     final double e;     final String f;     final String g;     //and more } 

The problem is that normally these fields have default values and therefore I do not want to always burden the user with a constructor with all of them. Most time, they just need to set a couple of them. There are a couple of ways to solve this:

  1. I would need lots of constructor with different signature.
  2. Create a bunch of set method of these field and only set those non-default value. But this somehow indicate a different semantics other than immutable nature.
  3. Create a new parameter class that is mutable and use that class as constructor.

None of that is totally satisfactory. Is there any other approach? Thanks. One way

like image 442
zggame Avatar asked Jul 07 '12 21:07

zggame


2 Answers

I would use a combination of a parameter class and a fluent builder API for creating the parameter:

public class A {     private final int a;     private final short b;     private final double e;     private final String g;      public static class Aparam {         private int a = 1;         private short b = 2;         private double e = 3.141593;         private String g = "NONE";          public Aparam a(int a) {             this.a = a;             return this;         }          public Aparam b(short b) {             this.b = b;             return this;         }          public Aparam e(double e) {             this.e = e;             return this;         }          public Aparam g(String g) {             this.g = g;             return this;         }          public A build() {             return new A(this);         }     }      public static Aparam a(int a) {         return new Aparam().a(a);     }      public static Aparam b(short b) {         return new Aparam().b(b);     }      public static Aparam e(double e) {         return new Aparam().e(e);     }      public static Aparam g(String g) {         return new Aparam().g(g);     }      public static A build() {         return new Aparam().build();     }      private A(Aparam p) {         this.a = p.a;         this.b = p.b;         this.e = p.e;         this.g = p.g;     }      @Override public String toString() {         return "{a=" + a + ",b=" + b + ",e=" + e + ",g=" + g + "}";     } } 

Then create instances of A like this:

A a1 = A.build(); A a2 = A.a(7).e(17.5).build(); A a3 = A.b((short)42).e(2.218282).g("fluent").build(); 

Class A is immutable, the parameters are optional, and the interface is fluent.

like image 111
David Conrad Avatar answered Oct 21 '22 10:10

David Conrad


Two things you can do:

  • Many constructor overloads
  • Use a builder object
like image 35
Jordão Avatar answered Oct 21 '22 10:10

Jordão