0

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.

Rossiar
  • 157
  • 1
  • 8
  • 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 01 '16 at 07: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 01 '16 at 11:07
  • 1
    @JacquesB your statements doesn't seem right to me, you can try to execute my code http://ideone.com/pU1SAb . Object(variable) provided by caller is modified here. – Vipin May 01 '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 01 '16 at 13:23
  • 2
    @JacquesB This question is about modifying the local copy of the variable, which is certainly possible. – Kevin Krumwiede May 02 '16 at 02:19
  • @KevinKrumwiede: No, the question states "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.". This suggest cal-by-reference semantics which is not something Java supports. Local copies of a parameter can obviously be modified, but that is invisible from the perspective of the caller. – JacquesB May 02 '16 at 05:56
  • A method call being final or not will make no difference to the calling context. I think what you are talking about is immutable (or immutable under certain conditions) this is an entirely separate concept to final. Make a variable final and note that you can still mutate the object it refers to, you just can't swap it for an entirely new object – Richard Tingle May 02 '16 at 06:52
  • Thanks to all above for clarifying - don't know why I thought Java had call-by-reference. Of course an object cannot be explicitly declared immutable in Java - so I guess this would be a limited feature anyway. – Rossiar May 04 '16 at 14:43

1 Answers1

7

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.

DeadMG
  • 36,794
  • 8
  • 70
  • 139
  • 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 01 '16 at 09: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 01 '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 01 '16 at 10:21