如何在调用另一个构造函数之前分割字符串

时间:2019-01-10 21:11:34

标签: java constructor

我尝试像这样重用我的构造函数:

    public final long x;
    public final long y;
    public final int level;
    private final int hash;
    public final Point tileCenter;

    public TileCoordinate(long x, long y, int level) {
        this.x = x;
        this.y = y;
        this.level = level;
        this.hash = Objects.hash(x, y, level);
        this.tileCenter = getTileCenter();
    }

    public TileCoordinate(String key) {
        String[] bits = key.split("-");
//      this.level = Integer.parseInt(bits[0]);
//      this.x = Long.parseLong(bits[1]);
//      this.y = Long.parseLong(bits[2]);
        this(Long.parseInt(bits[0]),Long.parseLong(bits[1]),Integer.parseLong(bits[2]));
        this.hash = Objects.hash(x, y, level);
        this.tileCenter = getTileCenter();
    }

由于我不想写this(Integer.parseInt(key.split("-")[0]),Long.parseLong(key.split("-")[1]),Long.parseLong(key.split("-")));,我有什么选择?

3 个答案:

答案 0 :(得分:4)

您似乎只在执行String[] bits = key.split("-");这行,以避免必须在对this()的延迟构造函数调用中调用3次,如果存在,则必须是其中的第一条语句构造函数。

不是委派给实际字段分配的构造函数,而是委托给处理字段分配的private方法。

public TileCoordinate(String key) {
    String[] bits = key.split("-");
    init(Long.parseInt(bits[0]),Long.parseLong(bits[1]),Integer.parseInt(bits[2]));
    this.hash = Objects.hash(x, y, level);
    this.tileCenter = getTileCenter();
}

private void init(long x, long y, int level) {
    // assign to fields here
}

请确保它是private,以便它不能被覆盖,否则泄漏this会成为问题。

您可能还需要在继续之前验证bits是否包含3个元素。

答案 1 :(得分:3)

this()super()的调用必须是构造函数中的第一条语句。解决该问题的一种方法是将第二个构造函数转换为Factory Method

public static TileCoordinate parseTitleCoordinate(String key) {
  String[] bits = key.split("-");
  long x = Long.parseLong(bits[0]);
  long y = Long.parseLong(bits[1]);
  long level = Long.parseLong(bits[2]);
  return new TitleCoordinate(x, y, level);
}

这将允许保留字段final

答案 2 :(得分:0)

可以重载init方法:

  public TileCoordinate(long x, long y, int level) {
      init(x, y, level);
  }

  public TileCoordinate(String key) {
      init(key);
  }

  private void init(String key) { 
      String[] bits = key.split("-");
      init(Long.parseLong(bits[0]),
           Long.parseLong(bits[1]),
           Integer.parseInt(bits[2]));
  }

  private void init(long x, long y, int level) { 
      this.setX(x);
      this.setY(y);
      this.setLevel(level);
  }

这保持了单一职责。

只有第二个init方法正在调用setter,其余的则是委托。