Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有最终未初始化字段的抽象类_Java_Oop - Fatal编程技术网

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

Java 具有最终未初始化字段的抽象类,java,oop,Java,Oop,我想知道下面的代码是否有意义,因为编译器警告“空白的最终字段对象可能尚未初始化”。有更好的方法吗 public abstract Test { protected final ArrayList<Object> objects; } public TestSubA extends Test { public TestSubA() { objects = new ArrayList<Objects>(20); // Other stuff }

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

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
  }
}
公共抽象测试{
受保护的最终ArrayList对象;
}
公共TestSubA扩展了测试{
公共TestSubA(){
对象=新的ArrayList(20);
//其他东西
}
}
公共TestSubB扩展了测试{
公共TestSubB(){
对象=新的ArrayList(100);
//其他东西
}
}

我将使字段成为最终字段,并强制构造函数向上传递值:

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
  }
}
公共抽象类测试{
私有最终ArrayList对象;
受保护的ArrayList getObjects(){
归还物品;
}
受保护测试(ArrayList对象){
this.objects=对象;
}
}
公共类TestSubA扩展了测试{
公共TestSubA(){
超级(新ArrayList(20));
//其他东西
}
}
公共类TestSubB扩展了Test{
公共TestSubB(){
超级(新ArrayList(100));
//其他东西
}
}

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

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

直接在子类的构造函数中初始化最终参数的问题是,您需要在一行中完成所有操作,因为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);
  }
}
公共抽象类测试{
受保护的最终ArrayList对象;
受保护测试(ArrayList对象){
this.objects=对象;
}
}
公共类TestSubA扩展了测试{
公共静态TestSubA build(){
ArrayList对象=新的ArrayList(20);
对象。放置(…);
//其他东西
返回新的TestSubA(对象);
}
私有TestSubA(ArrayList对象){
超级(对象);
}
}

+1击败了我——答案是一样的,只是有一些细微的差别(即使用int参数并调用super()而不是this())。谢谢。你为什么把它设为私有而不是受保护的,有什么具体原因吗?假设我想在子类中直接访问它。为什么你用this()而不是super()?@MCory@Lieven我猜这是智能手机的一个快速回答,在智能手机上,第一次就把所有事情都搞定并不容易。@Lieven:“this”是一个拼写错误-但我更喜欢在任何地方都是私有字段,并且不应该是您公开的API的一部分-其中包括派生类可以看到的内容。从字节码/验证器的角度来看,
final
表示仅由类本身分配(可以是未分配的,分配的倍数,由构造函数以外的方法分配(不能100%确定是否来自其他实例/静态方法))。oops,很抱歉这是一个复制/粘贴错误。我编辑了我的代码。+1:为了做正确的事情。