Christopher Meyer

About Christopher Meyer

Chris works as a researcher and is eagerly looking for bugs in SSL/TLS, the Java platform and various applications. In addition, he is primarily interested in secure coding and exploiting coding mistakes.

Using the final keyword on method parameters

After some own confusion which specific meaning final declared method parameters have this blog entry will try to clarify this.

At least the final keyword on method parameters can be seen as an indicator for the Java compiler that this parameter can not be reassigned to another reference. Java parameter handling is always Call by Value (yes, even when dealing with Objects) and here comes why.: It is true, that Java handles a reference to the Object when dealing with non-primitive data types. The Object itself is not passed from the callee to the target function! Instead a reference is passed that points to the desired Object. But this reference is not equal to the one on callee side since it is just a copy. What is passed to a function is a copied reference as value – ok, everyone’s still on board? :-) Maybe Java should use the more matching explanation Call by Copied Reference as Value.

To sum up:

Java exclusively passes ALL method parameters (primitive data types or references to objects) in Call by Value style!

As a proof for this let’s have a look at the following demo code and its output.

 
/**
 * Call by Value Test Application.
 *
 * @author Christopher Meyer
 * @version 0.1 
 * Apr 21, 2012
 */
public class CBVTest {

    public static void main(String[] args) {
        Integer mainInternInteger = new Integer(1);

        /*
         * Even references are copied during calls!
         *
         * Explanation Objects are never passed, only references to them, BUT
         * references are copied! So only reference COPIES reach the method.
         * Neither changes to the reference inside/outside the method will
         * influence the counterpart.
         *
         * Maybe it should be called "Call by Copied Reference as Value".
         */

        class RunMe implements Runnable {

            Integer runnerInternInteger;

            public RunMe(Integer i) {
                runnerInternInteger = i;

                /*
                 * The following operation will have no effect on the main
                 * thread, since the reference to "i" is a copied one.
                 * Interfacing the "caller" reference is prevented.
                 */
                i = new Integer(3);
            }

            @Override
            public void run() {
                while (true) {
                    System.out.println(runnerInternInteger.intValue() 
                            + "\t (runner intern value)");
                }
            }
        }

        Thread runner = new Thread(new RunMe(mainInternInteger));
        runner.start();

        // Create a new object and assign it to "mainInternInteger".
        mainInternInteger = new Integer(2);
        while (true) {
            System.out.println(
                    mainInternInteger.intValue() + "\t (main intern value)");
        }
    }
}

The output of the code looks like this:

...
2     (main intern value)
2     (main intern value)
2     (main intern value)
2     (main intern value)
1     (runner intern value)
2     (main intern value)
1     (runner intern value)
2     (main intern value)
1     (runner intern value)
2     (main intern value)
1     (runner intern value)
1     (runner intern value)
1     (runner intern value)
1     (runner intern value)
1     (runner intern value)
 ...

So neither the assignment to the handled parameter (i = new Integer(3)), nor the reassignment from the calling class (mainInternInteger = new Integer(2)) have any influence on each other.

So what is it worth if it isn’t really necessary?

If added to the Constructor of RunMe (public RunMe(final Integer i)) the reassignment i = new Integer(3) throws an exception: Exception in thread “main” java.lang.RuntimeException: Uncompilable source code – final parameter i may not be assigned. It prevents failures related to unintentional reassignment. Accidental assignments to the handled parameter will always fail! final forces a developer to produce accurate code.

The final keyword is not part of the method signature. So if declared final or not, the compiled code will be identical (everyone can easily check this by using diff). This means that a method can’t be overloaded by declaring the method parameters once final and once not. Since the byte code remains identical it also has absolutely no influence on performance.

To confuse even more keep in mind that inner classes require to define a variable final when the variable can be modified (for example when dealing with anonymous inner classes for Threads – if this isn’t clear to you consider multiple variables in the same context with identical names that can be altered).

Reference: Using the final keyword on method parameters from our JCG partner Christopher Meyer at the Java security and related topics blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


six × 9 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close