nemo
nemo

Reputation: 11

Constructor initialization of instance variables

If I have something like the code below as a constructor, is there a simple, shorthand way to do all the instance variable initializations in one line if all their names are the same as the parameter names?

private Quiz(int id, String name, int creatorId, Date timeCreated,
        int categoryId, boolean randomOrder, boolean multiPage,
        boolean immediateCorrection, boolean allowPractice) {
    this.id = id;
    this.name = name;
    this.creatorId = creatorId;
    this.timeCreated = timeCreated;
    this.categoryId = categoryId;
    this.randomOrder = randomOrder;
    this.multiPage = multiPage;
    this.immediateCorrection = immediateCorrection;
    this.allowPractice = allowPractice;
}

Upvotes: 1

Views: 2289

Answers (4)

DWoldrich
DWoldrich

Reputation: 4017

Project Lombok has a series of class annotations you can add to your class that will generate constructors of the kind you describe. Take a look at @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor here:

https://projectlombok.org/features/index.html

The other annotations available in Lombok are similarly magical for removing boilerplate from your classes, take a look. Lombok is fantastic and IntelliJ Idea has good plugin support for debugging and testing Lombok-annotated classes.

Upvotes: 1

You can use a factory method that acts like a constructor, but actually returns an anonymous subclass of the main class. The methods of the anonymous subclass can access the factory method parameters as long as they are declared final. So this technique can only be used for fields that never change.

import java.util.Date;

abstract class Quiz{

  static Quiz newQuiz(final int id, final String name, final int creatorId, final Date timeCreated,
                      final int categoryId, final boolean randomOrder, final boolean multiPage,
                      final boolean immediateCorrection, final boolean allowPractice) {

    // Return anonymous subclass of Quiz
    return new Quiz(){

      @Override
      public String someMethod() {
        // Methods can access newQuiz parameters
        return name + creatorId + categoryId + timeCreated;
      }

      @Override
      public boolean someOtherMethod() {
        // Methods can access newQuiz parameters
        return randomOrder && multiPage && allowPractice;
      }

    };
  }

  public abstract String someMethod();
  public abstract boolean someOtherMethod();


  public static void main(String[] args) {
    Quiz quiz = Quiz.newQuiz(111, "Fred", 222, new Date(), 333, false, true, false, true);
    System.out.println(quiz.someMethod());
    System.out.println(quiz.someOtherMethod());
  }

}

Upvotes: 0

Khanna111
Khanna111

Reputation: 3913

No there is not, but you should refer to the builder approach since there are a lot of parameters / arguments to the constructor in there.

The builder would make the object creation readable, less error prone and assists in thread safety as well.

Take a look at When would you use the Builder Pattern? for details and samples.

Upvotes: 2

Igor Uzhviev
Igor Uzhviev

Reputation: 308

Unfortunately there is no simpler way to initialize instance variable - you have to write such initialization code in a constructor.

However all modern IDE (like IntelliJ IDEA, Eclipse, etc.) can generate such constructors automatically based on instance variables, so you don't have to write such code manually. (For instance in IntelliJ IDEA press Alt+Insert, choose Constructor, select variables which you need and the constructor code will be generated).

Also, if you have so many variables which you need to pass and initialize in the constructor (and especially if not all of them are required) - consider to use patter Builder (unfortunately you will have to write even more code!). Here is an example how to implement Builder: http://www.javacodegeeks.com/2013/01/the-builder-pattern-in-practice.html

Upvotes: 4

Related Questions