2

Let's say i have a method being called by passing an object.

public String retrieveXyz(Criteria criteria){

//get some info out of criteria and do something.

}

Is it a good practice to make the criteria final so that this handler cannot be used to target some other object other than the passed one or its an overhead as this doesn't protect the object state from getting changed.

public String retrieveXyz(final Criteria criteria){

//get some info out of criteria and do something.

}
crush
  • 16,713
  • 9
  • 59
  • 100
Vivek Vermani
  • 1,934
  • 18
  • 45
  • I never had to use `final` method parameters. I am curious why they are for actually. – Antoniossss Feb 04 '14 at 21:54
  • If you change the reference held in `criteria` within the function, it won't change the reference the variable outside of the function held. – crush Feb 04 '14 at 21:54
  • If the parameter doesn't need to be marked as `final`, then leave it as is. In fact, marking it as `final` means that you cannot change its value i.e. you cannot do `criteria = new Criteria();` inside that method. – Luiggi Mendoza Feb 04 '14 at 21:54
  • 2
    @Antoniossss it is useful when you need to use this parameter inside the anonymous implementation of an interface e.g. implementing `Runnable` to work with threads in your method. – Luiggi Mendoza Feb 04 '14 at 21:55
  • @LuiggiMendoza Perhaps that is the intended behavior in some circumstance, though I'm not sure why. – crush Feb 04 '14 at 21:56
  • 1
    http://stackoverflow.com/questions/316352/why-would-one-mark-local-variables-and-method-parameters-as-final-in-java duplicate This allows compiler optimisation as well as useful warnings if you try to modify the reference. You should certainly do this, and turn on the setting in your IDE that does it for you automatically. –  Feb 04 '14 at 21:59
  • 2
    @Stretch Do you actually do this in your code? The price in verbosity is steep, which is the only reason I don't use it. Many will agree that `final` should have been the default, and `var` or similar would have to be used to mark a variable non-final. – Marko Topolnik Feb 04 '14 at 22:13
  • @MarkoTopolnik The only reason I do it is out of habit from `C++` where I'd often pass a `const` reference. `const string& str`. It's meaning is slightly different in Java. – crush Feb 04 '14 at 22:20
  • @crush I wouldn't call the difference slight :) – Marko Topolnik Feb 04 '14 at 22:23
  • @Stretch I respectfully decline to stoop down to your level of discourse, but note this: if you are using PMD, you are committing a double offence against your codebase---imposing clutter on your codebase, *and* doing it for no good reason. PMD can enforce the effective finalness of parameters with the `AvoidReassigningParameters` rule. – Marko Topolnik Feb 05 '14 at 09:01
  • Another point on "compiler optimizations": even a rudimentary compiler will have no problem discerning that a local variable is *effectively final*. You have mixed up the importance of `final` on *instance* variables with its triviality when applied to *local* variables. Java 7 has already adopted the concept of effective finalness in order to relax the rules which enforce explicit `final` on local variables. (@Stretch) – Marko Topolnik Feb 05 '14 at 10:10

3 Answers3

5

If you mark a method parameter as final, you can't modify the parameter's value within the scope of the method:

public void xyz(final String parameter) {
    parameter = "..." //compiler error!
}

Understand that the value of parameter is the reference to the object passed to the method, and not the value of the object itself.

By marking the method parameter as final, the compiler will throw an error upon compilation. This serves as a reminder that you should not modify the value of the parameter within your method.

It's considered a bad practice to modify the original parameter within your method.[1]

If the value of the parameter can change to reference another object, it might not be immediately clear what object is being referenced at any given point within the body of your method.

Consider the following:

public void xyz(String parameter) {
    //Complicated logic that might span 20-30 lines.

    parameter = "Joe";

    //More complicated logic that might span a few lines.

    //New logic being added that needs reference to the value of the parameter.
}

In a complicated method, like above, it might be difficult for a programmer to identify what object parameter references. Furthermore, if the programmer needs a reference to parameter he no longer has one.


  1. Is it a good practice to change arguments in Java
Community
  • 1
  • 1
AlfredoCasado
  • 818
  • 5
  • 7
  • This seems to be the most accurate answer here, though, I believe it could use a little bit of language cleanup. Do you mind if we help @AlfredoCasado? – crush Feb 04 '14 at 22:10
  • I've edited the answer so that, hopefully, it is more clearly written in English. If I've said something incorrect, please change it! Thanks. – crush Feb 04 '14 at 22:29
  • Additionally, if someone can help me find a credible reference that states changing the original parameter is bad practice, that would be nice. – crush Feb 04 '14 at 22:31
3

final in method parameter has no difference in most situations, you still won't be able to change its address inside the method but its attributes can be changed.

You might need to use final sometimes when you have something like below, run method won't be compile unless a is final, though you can assign it to other final object etc, but why bother that.

public void foo(final String a) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.print(a);
        }
    }); 
}
Orhan Obut
  • 8,756
  • 5
  • 32
  • 42
  • Borrowing @delnan's comment below: *"Well, duh. Making x immutable doesn't prevent mutation of y. That doesn't mean it's pointless."* – crush Feb 04 '14 at 22:02
  • first of all, you are not making it immutable, immutable surely prevent changes, final keyword just make it that you can't change its address in the memory. and I couldn't actually understand what you wanted to mean in this comment. – Orhan Obut Feb 04 '14 at 22:05
  • The point was that no one should expect `final` to prevent the modification of the fields of an object. It should only be expected to prevent the reassignment of the variable to which `final` applies. Thus, your rhetoric on *"you still won't be able to change its address inside the method but its attributes can be changed."* doesn't add anything meaningful to the conversation. – crush Feb 04 '14 at 22:06
  • It *is* making "it" immutable. Where "it" refers to the reference. Yes, the object remains mutable, and yes, that's not ideal, but there are other things whose mutability is of interest. –  Feb 04 '14 at 22:07
  • @crush, just double checked the question and you are right, the question already mention about object state which I missed. – Orhan Obut Feb 04 '14 at 22:15
  • @delnan if it refers the reference that's true but I think in here it refers the object attributes. – Orhan Obut Feb 04 '14 at 22:17
  • @nr4bt Of course *you* can talk about object mutability, but people who understand `final` mean the right thing when they say "slap `final` onto it to make it immutable". –  Feb 04 '14 at 22:19
1

PMD would advise you to do this: http://pmd.sourceforge.net/pmd-4.3/rules/optimizations.html

This allows for useful optimisations, and warns when you might do something undesirable in your code. IDEs like Eclipse and Intellij have options to do this automatically, and it is sensible to do so.