1

这是我的示例代码:

public class ExternalizableClass implements Externalizable
{
  final int id;

  public ExternalizableClass()
  {
    id = 0;
  }

  public ExternalizableClass(int i)
  {
    id = i;
  }

  @Override
  public void writeExternal(ObjectOutput out) throws IOException
  {
    out.writeInt(id);
  }

  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
  {
    id = in.readInt();
  }

  @Override
  public String toString()
  {
    return "id: " + id;
  }
}

它无法编译,因为id = in.readInt();Error:(36, 5) java: cannot assign a value to final variable id. 但是,我可以想到真实的用例,其中不可变字段(例如 id)需要外部化,同时我们还希望保持其不变性。

那么解决这个问题的正确方法是什么?

4

1 回答 1

-1

read 函数对于 final 字段的想法没有多大意义,因为无论它被初始化为什么值,都应该永远是它的值。读取功能不应该能够改变它。

显然,用构造函数初始化的对象public ExternalizableClass(int i)不应该能够读取新值——如果它们可以,那么它们的id值就不是真正的最终值。我能看到的唯一另一种方法是让默认构造函数初始化一个“未读”实例,允许您稍后调用 read 。但是,这确实需要删除 final 修饰符并解决此问题。所以看起来像这样:

public class ExternalizableClass implements Externalizable
{
  private int id;
  private boolean initted;

  int getId(){
      return id;
  }

  public ExternalizableClass(int i, boolean initted){
      id = i;
      this.initted = initted;
  }

  public ExternalizableClass(){
      this(0, true); //Default instances can't be changed
  }

  public ExternalizableClass(int i)
  {
    this(i, true); //Instances from this constructor can't be changed either
  }

  @Override
  public void writeExternal(ObjectOutput out) throws RuntimeException, IOException
  {
    if(! initted)
        throw new RuntimeException("Can't write unitialized instance, " + this);
    out.writeInt(id);
  }

  @Override
  public void readExternal(ObjectInput in) throws RuntimeException, IOException, ClassNotFoundException
  {
    if(initted)
        throw new RuntimeException("Can't Read into already initialized object ," + this);
    id = in.readInt();
    initted = true;
  }

  @Override
  public String toString()
  {
    if(initted) return "id: " + id;
    else return "No id";
  }
}
于 2014-12-27T03:58:00.840 回答