在Java中使抽象方法参数最终

时间:2013-07-18 09:42:43

标签: java abstract final

我有一个带抽象方法的抽象类,我想要的参数是final - 也就是说,我不想允许抽象类的实现。重新分配参数的方法。

编辑:这样做的动机本身并不是不可变性,这更多地与对象的设计有关。 (事实上​​,在我的用例中,参数是将在抽象方法的实现中进行变异的集合。)相反,我想与实现我的抽象类/方法的任何人沟通,不应该重新分配这些变量。我知道我可以通过java-doc进行沟通,但我正在寻找更合同的东西 - 他们必须遵循,而不是仅仅被引导跟随。

在非抽象方法中,我可以使用final关键字执行此操作 - 例如:

public class MyClazz {
  public void doSomething(final int finalParameter){
    finalParameter++; // compile error - cannot assign a value to final variable
  }
}

但是,如果我在抽象方法中使用final关键字,则这不构成合同的一部分 - 也就是说,抽象方法的实现不需要final关键字,并且参数可以重新分配:

public abstract class MyAbstractClazz {
  public abstract void doSomething(final int finalVariable);
}

public class MyExtendedClazz extends MyAbstractClazz {
  @Override
  public void doSomething(int finalVariable) { // does not require final keyword
    finalVariable++; // so the variable is modifiable
  }
}

正如对此SO Question的回答所指出的,final关键字不构成方法签名的一部分,这就是为什么抽象类的实现不需要它。

所以,有两个问题:

  1. 为什么final关键字不属于方法签名?我明白它不是, 但是我想知道它是否是一个特殊的原因。

  2. 鉴于final关键字不是方法签名的一部分,是否有另一种方法可以使抽象方法中的参数无法分配?

  3. 其他研究:

    • SO question触及同一问题,但我的两个问题都没有。事实上,第二个问题是明确提出的,但没有得到答案。

    • 最终关键字上的很多问题/博客等都是"the final word"。但是,关于这个问题,相关评论如下(尽管有用,但没有解决我的两个问题):

      

    请注意,最终参数不被视为方法签名的一部分,在解析方法调用时编译器会忽略它们。参数可以声明为final(或不声明),不会影响方法的覆盖方式。

2 个答案:

答案 0 :(得分:9)

  

我有一个带抽象方法的抽象类,我想要最终的参数 - 也就是说,我不想允许实现抽象类&重新分配参数的方法。

为什么不呢?这是实现细节。它对调用代码是不可观察的,因此抽象方法没有理由指定它。这就是为什么它不是方法签名的一部分 - 就像synchronized不是。

一种方法应该实施其记录的合同 - 但它如何选择这样做取决于它。合同不能说参数的最终结果有用,因为Java总是使用pass-by-value。

答案 1 :(得分:1)

参数是按值传递的,如果你使用某个变量调用方法,即使你在方法中重新分配参数,这个变量也不会被修改,这就是为什么它对 final 没有意义成为合同的一部分。