【问题标题】:Initialize final variable within constructor in another method在另一个方法中初始化构造函数中的最终变量
【发布时间】:2012-08-01 20:04:06
【问题描述】:

我有一个问题并不大,但仍然让我思考如何使用 Java 构造函数和方法。

我有一个代表半径的常量,我声明为 final,并且将其公开给所有人查看。当我永远不会改变半径时,我不希望我的代码被 getRadius() 方法弄得乱七八糟。

我想在构造函数中初始化常量,因为我想在分配半径之前应用某些条件,必须满足某些条件。但是,这些条件确实会占用一些空间,我想将它们放在其他方法中,以使构造函数更简洁。

整个事情最初看起来像这样

public MyProblematicClass {
   public final int radius;
   public MyProblematicClass(... variables ...) {
      if(... long criteria ...) {
         radius = n;
      }
   }
}

我希望它最终会像这样

public MyProblematicClass {
       public final int radius;
       public MyProblematicClass(... variables ...) {
          this.setRadiuswithCriteria(criteria);
}

private void setRadiuswithCriteria(criteria crit) {
   if(... crit ...) {
      radius = n;
   }

我知道我可能会将该方法用于其他目的,这就是给我一个“空白字段 RADIUS 可能尚未初始化”的原因,所以我想知道是否有办法添加一个方法为了清洁起见,只会在构造函数中使用。

【问题讨论】:

  • 所有 CAPS 是 Java 中用于常量(又名静态成员)的约定,而不是不变的 final,只需使用正常的半径命名策略即可。
  • 将您的 RADIUS 变量声明为私有,并仅允许通过 getRadius 访问它。阅读有关不可变对象的更多信息,以及如何限制其变量值的变化
  • @SanjayT.Sharma 感谢您指出这一点,除了基础知识之外,我对命名约定不太了解...我专门在声明代码之外知道哪些变量我可以'不要修改,我会在问题中更正。
  • @RedOrav:开始接触新事物永远不会太晚。这是马嘴里的官方naming convention link。 :)

标签: java android


【解决方案1】:

怎么样(使用小型大写字母表示半径,因为它不是常数,正如 cmets 中指出的那样):

public MyProblematicClass(... variables ...) {
    radius = getRadiusWithCriteria(criteria);
}

private int getRadiusWithCriteria(criteria crit) {
   if(... crit ...) {
      return n;
   } else {
      return 0;
   }
}

【讨论】:

  • 函数并不总是返回值。只有 C 允许这样做,Java 不允许。
  • @peenut 我不明白你的评论。什么意思?
  • @assylias 我认为他的意思是你并不总是返回一个值,这是一个编译器错误。如果不满足任何条件或其他情况,我的默认值为 0。我认为这个解决方案很棒而且很简单,但是假设我在方法中有两个最终变量,radius1 和 radius2。
  • @RedOrav 如果您有 2 个变量,您可以使用 2 个方法,或者让 getRadius 方法返回结果列表/数组,然后您可以在构造函数中分配给您的 2 个变量。跨度>
  • @assylias 是的,第二个建议太棒了,非常感谢,我对这个问题太感兴趣了,看不到答案。
【解决方案2】:

您不能在构造函数之外分配给最终变量。如你所说,方法:

setRadiuswithCriteria(criteria crit) {
   if(... crit ...) {
      RADIUS = n;
   }

可以在构造函数之外使用。

您必须在构造函数中将最终变量设置为某个值,而不仅仅是在检查某些条件之后(总是,而不是有时)。

但是,您可以使用某个函数的返回值将代码移到构造函数之外。示例:

class MyClass {
    private final double i;
    public MyClass() {
        i = someCalculation();
    }
    private double someCalculation() {
        return Math.random();
    }
}

【讨论】:

  • 我在构造函数中检查了我的标准,我只是想把它全部放在另一个函数中以保持整洁。我也会赞成这个答案,尽管它与 assylias 相同。
【解决方案3】:

这样怎么样?

public MyProblematicClass {
    public final int RADIUS;
    public MyProblematicClass(... variables ...) {
       RADIUS = this.setRadiuswithCriteria(criteria);
}

private int setRadiuswithCriteria(criteria crit) {
if(... crit ...) {
    return n;
}
return 0;
}

【讨论】:

    猜你喜欢
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2020-09-27
    • 2015-02-19
    • 1970-01-01
    • 2011-07-02
    相关资源
    最近更新 更多