-1

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.

closed as primarily opinion-based by Adam Zuckerman, gnat, 5gon12eder, Jörg W Mittag, Ben Cottrell May 1 '16 at 11:34

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 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
6

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.

  • 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.