10
Sep 12

Final method arguments

Among the many Checktyle rules there is this particular one (FinalParameters) stating that all method parameters should be declared as final in method implementations. This requirement might seem unnecessary or even silly but it is there not without a reason. An obedience to the rule might be observed in some open source projects so go ahead and see how it works in practice.

The reason to always add the final keyword in front of method parameters is to prevent parameters to be reassigned by mistake. It is a bad practice to do so deliberately anyway. Together with final local variables (or constants when a primitive), final private class fields and some defensive coding (cloning objects passed as parameters when willing to mutate) a Java environment could become a better place. Especially for functional programmers. The ideal would be to deal with immutable objects whenever possible.

Some people may dislike the additional clutter caused by addition of final in every possible place. Sorry, Java was designed this way so to follow the right path you just need to accept the pain. There are also some situations when putting final is not possible for fields, e.g. when using field based dependency injection in frameworks like Spring or Guice. Final naturally shouldn’t also be used with local primitives that we wish to mutate, like loop counters.

IDEs can be helpful in covering code with final. In Eclipse, there’s an option to add final modifier to every place suitable after save operation (Window->Preferences->Java->Editor->Save actions, Additional actions checkbox, then Configure->Code style). The already mentioned checkstyle with the FinalParameters rule activated may be used to spot the appropriate places as well.

Below are some snippets showing different aspects of the concept:

class MyWebController {
	private static final String dummyView = "dummyView";

	public String actionOne(final HttpRequest request, 
			final String param1,
			final String param2) {
		// TEN LINES OF CODE
		//
		//
		// BZZZ
		//
		//
		//
		//
		//
		// BuzzzZ

		/*
		 * param1 was not modified since it's an immutable String and final
		 * 
		 * the view 'variable' was made final automatically by Eclipse IDE
		 */
		final String view = dummyView + param1;

		return view;
	}
}

Final in loops:

class LoopFinalExample {
	public void test() {
		final Object[] array = {new Object(), new Object()};
		
		//foreach loop might use final for greater safety of preserving
		//an assignement to the object currently pointed by iterator 
		 
		for (final Object object : array) {
			System.out.println(object.toString());
		}
		
		// the same is not possible with for loop because usually there
		// is a desired reassignment present 
		 
		for (int i = 0; i < array.length; i++) {
			System.out.println(array[i].toString());
		}
	}
}

Remember that you can use final for local variables to quickly analyze spaghetti code which uses a lot of reassignments. The same applies to your own code if you want to announce your intent to the future reader! And always have in mind that Java final is not the same as C++ const!!

Leave a Reply

Your email address will not be published.