Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making abstract method parameters final in Java

I have an abstract class with an abstract method, the parameters for which I want to be final - that is, I do not want to allow implementations of the abstract class & method to reassign the parameter.

EDIT: The motivation for this is not immutability per se, which is more to do with the design of the objects. (In fact, in my use case, the parameter is collection which will be mutated in the implementation of the abstract method.) Rather, I want to communicate to anyone implementing my abstract class/method that these variables should not be reassigned. I know that I can communicate that via the java-doc, but I was looking for something more contractual - that they would have to follow, rather than just be guided to follow.

In a non-abstract method, I can do this using the final keyword - for example:

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

However, if I use the final keyword in an abstract method, this does not form part of the contract - that is, implementations of the abstract method do not require the final keyword, and the parameter can be reassigned:

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
  }
}

As pointed out in answers to this SO Question, the final keyword does not form part of the method signature, which is why the implementation of the abstract class does not require it.

So, there are two questions:

  1. Why is the final keyword not part of the method signature? I understand that it isn't, but I want to know if there's a particular reason why it isn't.

  2. Given that the final keyword is not part of the method signature, is there an alternative way of making parameters in an abstract method unassignable?

Other research:

  • this SO question touches on the same issue, but doesn't either of my two questions. In fact, the second question is explicitly asked, but does not receive an answer.

  • lots of questions/blogs etc. on the final keyword refer to "the final word". However, with respect to this question, the relevant comment is as follows (which, while useful, doesn't address my two questions):

Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls. Parameters can be declared final (or not) with no influence on how the method is overriden.

like image 529
amaidment Avatar asked Jul 18 '13 09:07

amaidment


2 Answers

I have an abstract class with an abstract method, the parameters for which I want to be final - that is, I do not want to allow implementations of the abstract class & method to reassign the parameter.

Why not? That's an implementation detail. It's unobservable to the calling code, so there's no reason why the abstract method should specify it. That's why it's not part of the method signature, either - just like synchronized isn't.

A method should implement its documented contract - but how it chooses to do so is up to it. The contract can't say anything useful about the finality of a parameter, as Java always uses pass-by-value.

like image 95
Jon Skeet Avatar answered Nov 14 '22 23:11

Jon Skeet


Parameters are passed by value, if you call the method using certain variable, this variable wont get modified even if you reassign the parameter inside the method, that's why it doesn't make sense for final to be part of the contract.

like image 20
morgano Avatar answered Nov 14 '22 23:11

morgano