Say I have a method that writes a string to a file:

public void write(String content, File out) {
    // writes content to out

If I want to protect the parameters and ensure that they are not re-assigned a new value within this write method, I can use the final keyword to prevent this:

public void write(final String content, final File out) {
    // writes content to out

From what I know of best practice (and this handy question here), this is a good thing - as it is not clear behaviour if a method modifies what it has been given. However, I do still understand that sometimes we will need to do this and so the functionality should be built in to Java to allow this.

My question is, why do I have to explicitly state that a parameter is final and not the other way around? Why can't all method parameters (or even all parameters?) be implicitly final - and I have to use a new Java keyword (for instanceunstable) to explicitly be able to modify a parameter.

public String write(unstable String content, File out) {
    // writes content to out
    // then for some mad reason, this happens
    content = "Done";
    return content;

This could be passed along into the Javadoc so that a caller could explicitly know that a variable they are providing is not safe and will be modified.

  • 3
    Unfortunately, the only answer we can provide to "Why did {somebody} do {something} instead of {my way}?" is "You have to ask {somebody}". In this case, {somebody} would be Oracle or its predecessors in Java. – Adam Zuckerman May 1 '16 at 7:24
  • 1
    @Rossair: Your wish is already granted! Java does not support call-by-reference, so a variable provided by the caller as parameter is never modified by a method. – JacquesB May 1 '16 at 11:07
  • 1
    @JacquesB your statements doesn't seem right to me, you can try to execute my code ideone.com/pU1SAb . Object(variable) provided by caller is modified here. – Vipin May 1 '16 at 13:13
  • @Vipin: The variable and the object are different things. The variable aDog contains a reference but is passed by value. The called function foo cannot change the variable aDog to point to a different object. It can change the field name of the Dog instance, but that is a different issue. – JacquesB May 1 '16 at 13:23
  • 2
    @JacquesB This question is about modifying the local copy of the variable, which is certainly possible. – Kevin Krumwiede May 2 '16 at 2:19

You seem to be under the misconception that when content is modified inside write, that modification is visible to the caller.

It is not.

It's when you write to properties on it that those changes are visible to the caller, but final does not protect against this in any way.

| improve this answer | |
  • 1
    Or, if you know C++, think of final Foo as something like Foo *const, rather than const Foo&. For primitive types, final int actually is const int, however. – 5gon12eder May 1 '16 at 9:32
  • That's exactly why I'm saying this is not how it should be - the caller has no idea what can happen to their variables! – Rossiar May 1 '16 at 10:12
  • But... the callee can't mutate their variables. Hell, the caller may not even have a variable, it may be an expression. – DeadMG May 1 '16 at 10:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.