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

在Java中使抽象方法参数最终化,java,abstract,final,Java,Abstract,Final,我有一个抽象类和一个抽象方法,参数我希望是final——也就是说,我不想让抽象类和方法的实现重新分配参数 编辑:这样做的动机不是不变性本身,这更多地与对象的设计有关。(事实上,在我的用例中,参数是collection,它将在抽象方法的实现中发生变化。)相反,我想告诉任何实现我的抽象类/方法的人,这些变量不应该被重新分配。我知道我可以通过java文档进行沟通,但我一直在寻找更具契约性的东西——他们必须遵循,而不仅仅是被引导遵循 在非抽象方法中,我可以使用final关键字执行此操作-例如: publ

我有一个抽象类和一个抽象方法,参数我希望是
final
——也就是说,我不想让抽象类和方法的实现重新分配参数

编辑:这样做的动机不是不变性本身,这更多地与对象的设计有关。(事实上,在我的用例中,参数是collection,它将在抽象方法的实现中发生变化。)相反,我想告诉任何实现我的抽象类/方法的人,这些变量不应该被重新分配。我知道我可以通过java文档进行沟通,但我一直在寻找更具契约性的东西——他们必须遵循,而不仅仅是被引导遵循

在非抽象方法中,我可以使用
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
  }
}
正如对此的回答中指出的那样,
final
关键字不构成方法签名的一部分,这就是抽象类的实现不需要它的原因

因此,有两个问题:

  • 为什么
    final
    关键字不是方法签名的一部分?我知道不是这样的, 但我想知道是否有特别的原因

  • 鉴于
    final
    关键字不是方法签名的一部分,是否有其他方法使抽象方法中的参数不可分配

  • 其他研究:

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

    • 关于最后一个关键字的许多问题/博客等请参考。然而,关于这个问题,相关评论如下(虽然有用,但没有解决我的两个问题):

    请注意,最终参数不被视为方法签名的一部分,并且在解析方法调用时被编译器忽略。参数可以声明为final(或not),而不影响重写方法的方式

    我有一个带有抽象方法的抽象类,参数是我想要的最终参数——也就是说,我不想让抽象类和方法的实现重新分配参数

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


    一个方法应该实现其文档化的契约——但它如何选择实现则取决于它。合同不能说明任何关于参数最终性的有用信息,因为Java总是使用按值传递。

    参数是按值传递的,如果使用某个变量调用方法,即使在方法内部重新分配参数,该变量也不会被修改,这就是为什么将final作为契约的一部分是没有意义的。

    但即使方法重新分配传递给它的变量,它也不会对调用方产生影响,因为对象引用是按值传递的。如果你通过修改对象的状态来改变它,事情会变得更糟。你到底想实现什么?不变性?@ErikPragt-修正了关于动机的问题。好的,谢谢-这就解释了为什么它不是签名的一部分。我已经对我的问题进行了编辑,对我的动机做了更多的说明,但我希望我能做的最好的事情是在文档中指出预期的实现。@AMAID:我认为你没有抓住要点-为什么有人会关心方法实现是否改变了参数的值?这完全是对外界隐藏的。你说“这些变量不应该被重新分配”-为什么你关心这个方法是如何实现的?如果一个实现在重新分配参数时恰好更干净,那么您为什么要阻止它呢?这些都是好的、有用的问题。。。我意识到,所有这些问题的答案都是“我不应该”。@amaidment:Excellent:)“Java总是使用按值传递”,如果您接受这一点,那么对于对象,传递的是指向对象的指针(您不必使用任何魔法)。