Подтвердить что ты не робот

Абстрактный класс с конечным неинициализированным полем

Мне было интересно, имеет ли смысл код ниже, поскольку компилятор предупреждает, что "пустые конечные объекты поля могут быть не инициализированы". Есть ли лучший способ сделать это?

public abstract Test {
  protected final ArrayList<Object> objects;
}

public TestSubA extends Test {

  public TestSubA() {
    objects = new ArrayList<Objects>(20);
    // Other stuff
  }
}

public TestSubB extends Test {

  public TestSubB() {
    objects = new ArrayList<Objects>(100);
    // Other stuff
  }
}
4b9b3361

Ответ 1

Я бы сделал поле окончательным и заставил конструкторы передать значение вверх:

public abstract class Test {
  private final ArrayList<Object> objects;

  protected ArrayList<Object> getObjects() {
    return objects;
  }

  protected Test(ArrayList<Object> objects) {
    this.objects = objects;
  }
}

public class TestSubA extends Test {

  public TestSubA() {
    super(new ArrayList<Object>(20));
    // Other stuff
  }
}

public class TestSubB extends Test {

  public TestSubB() {
    super(new ArrayList<Object>(100));
    // Other stuff
  }
}

Ответ 2

Проблема с инициализацией конечных параметров непосредственно в конструкторе подклассов заключается в том, что вам нужно сделать все это в одной строке, так как super() должен быть первым выражением конструктора. Поэтому вместо этого я предпочитаю сделать конструктор непубличным и сделать метод статической сборки следующим образом:

public abstract class Test {
  protected final ArrayList<Object> objects;

  protected Test(ArrayList<Object> objects) {
    this.objects = objects;
  }
}

public class TestSubA extends Test {
  public static TestSubA build() {
    ArrayList<Object> objects = new ArrayList<Object>(20);
    objects.put(...);
    // Other stuff
    return new TestSubA(objects);
  }

  private TestSubA(ArrayList<Object> objects) {
    super(objects);
  }
}

Ответ 3

Создайте объекты в конструкторе абстрактного класса и просто передайте разницу этому конструктору.

Ответ 4

Вообще говоря, было бы лучше иметь конструктор в базовом классе, который всегда устанавливает поле, а не иметь конструктор по умолчанию, который его не задает. Подклассы могут затем явно передать параметр в первой строке своего конструктора, используя super (value)