java 具有最终未初始化字段的抽象类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2327509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 20:37:59  来源:igfitidea点击:

Abstract class with final uninitialized field

javaoop

提问by Cantillon

I was wondering if the below code makes any sense, since the compiler warns that "the blank final field objects may not have been initialized". Is there a better way of doing this?

我想知道下面的代码是否有意义,因为编译器警告说“空白的最终字段对象可能尚未初始化”。有没有更好的方法来做到这一点?

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
  }
}

采纳答案by Jon Skeet

I would make the field final and force the constructors to pass the value up:

我会将字段设为 final 并强制构造函数向上传递值:

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
  }
}

回答by qwertzguy

The problem with initializing the final parameters directly in the constructor of the sub-classes is that you need to do it all in one line since super() must be the first statement of the constructor. So instead, I prefer to make the constructor non-public and make a static build method like this:

直接在子类的构造函数中初始化最终参数的问题在于,您需要在一行中完成所有操作,因为 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);
  }
}

回答by ctrlShiftBryan

Instantiate the objects in the abstract class constructor and just pass the difference to the that constructor.

实例化抽象类构造函数中的对象,并将差异传递给该构造函数。

回答by Uri

Generally speaking, it might be better to have a constructor in the base class that always sets the field, and not have a default constructor that doesn't set it. The subclasses can then explicitly pass the parameter in the first line of their constructor using super(value)

一般来说,最好在基类中有一个总是设置字段的构造函数,而不是没有设置它的默认构造函数。然后子类可以使用 super(value) 在其构造函数的第一行中显式传递参数