Java has a lot of boilerplate code, although each new version tries to remove a bit more every time. One area particularly affected is when you have to declare and initialise lists, maps or sets (some of it hopefully simplified in Java 7). Here’s some sample code:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
...
Map<String, String> map = new HashMap<String, String>();
List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>();
String[] array = new String[] {};
To create any of these, you have to type a lot. Sometimes you make a mistake and have to retype. And half a minute later you’ve got one line of code that just declares a list. Also, you can have Eclipse automatically add imports when you save, but Eclipse normally can’t guess the correct List, instead prompting you to choose between java.util.List and java.awt.List (why isn’t there an option to use the former as the default?).
But Eclipse templates can help you avoid the hassle. Not only will it create the correct import statements, but also remove the effort of typing out the same type in the interface and implementation collection. If you’re new to templates, then see this tip to get an overview.
When you’re writing JUnit tests, you’ll often find yourself repeating the same boilerplate code. Take the following code:
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class EngineTest {
@Before
public void setup() {
...
}
@Test
public void test() throws Exception {
...
}
@After
public void tearDown() {
...
}
}
If you want to add a test, you have to somehow add lines 3, 11, 12 and 14 before you even get to the actual test. The same holds for setup and teardown code. We know that Eclipse can help with adding imports automatically when you save or autocomplete, but it still takes time to get everything in place.
Eclipse templates can help take away the drudgery by adding all this boilerplate code automatically. It can automatically add a test, setup and teardown methods together with calls to assertEquals, assertTrue and others. I’m assuming JUnit 4 in all the templates. If you’re new to templates, then see this tip to get an overview.
Logging statements have taken up a nice chunk of my programming life. Info, debug and warning statements are common, especially since some team standards require that logging be done consistently (eg. at the start and end of all methods). Take the following code:
import org.apache.log4j.Logger;
...
public class Engine {
private final static Logger logger = Logger.getLogger(Engine.class);
public void someMethod() {
...
logger.debug("Doing something here");
...
}
To get the statement on line 8 you first have to insert line 4, generate the import on line 1 (eg. with Ctrl+Shift+O) and then move back to line 8 to type out the statement. That’s a lot of time for just one statement.
So here are some templates to help with this. The templates assume log4j since most people use that (right?), but can easily be adapted for Java Logging or other framework. If you’re new to templates, then see this tip to get an overview.
You may find yourself having to write the following code once too often, especially at the start of a method to validate arguments:
if (account == null) {
throw new IllegalArgumentException("Account is required");
}
//Or for strings
if (name == null || name.length() == 0) { //Or even StringUtils.isBlank() of Apache Commons
throw new IllegalArgumentException("Name is required");
}
Well, here are templates that makes it easy to validate an object or string and throw an IllegalArgumentException if it isn’t.
if (${var} == null) {
throw new IllegalArgumentException("${message}");
}
Name
errifblank
Context
Java statements
Pattern
if (${string:var(java.lang.String)} == null || ${string}.length() == 0) {
throw new IllegalArgumentException("${message}");
}
Name
errifblank (StringUtils)
Context
Java statements
Pattern
if (isBlank(${string:var(java.lang.String)})) {
throw new IllegalArgumentException("${message}");
}${:importStatic('org.apache.commons.lang.StringUtils.*')}
We’re still waiting for closures to come to Java – the saga continues. Until then we’ll need to write the filter boilerplate code manually. Filter loops often take an input array/collection, match each element with a condition and, if the condition matches, adds the element to another, filtered list. Here’s an example:
List<String> filteredNames = new ArrayList<String>();
for (String name : names) { //names is the original String Collection/array
if (name.contains("Sam")) {
filteredNames.add(name);
}
}
This code is tedious, error-prone and a time-waster. It takes a minute or two or even longer to write without any errors.
You can use Eclipse templates to generate a filter loop in about 20 seconds. If you haven’t worked with templates before, see this post for an overview.
I’ve created a template that produces a List declaration, enhanced for loop, if statement and an add to the filtered list. The list’s type is taken from the nearest array/collection in scope so should be a fairly good match. It even generates import statements for the List and ArrayList.
You can either import the template (recommended; much faster) or create the template manually.
We constantly have to check for nulls in Java. There are ways/ideas to cut down on them (eg. Safe Navigation Operator, type annotations, Null Object, better API design) but they’re either not here yet or not used often enough. So you’ll often need code similar to the following:
Transport transport = SomeAPI.createTransport(...);
//...
if (transport != null) {
//... Do something with transport...
if (transport.getSomething() != null) {
//... Do something with transport.getSomething ...
}
}
Typing the null-check is fine until you have to retype it 5 times a day, every day for 10 years (well, at least it feels like that).
You can use an Eclipse template to stop the madness. If you haven’t worked with templates before, see this post for an overview.
I’ve created a template that produces an if-statement with a not-null check on a variable that Eclipse will guess at first but give you the option to override it.
You can either import the template (recommended; much faster) or create the template manually.
I discussed templates and why to use them in another post. Basically, we use them to eliminate the pesky, repetitive code zombies. I also showed some built-in templates and what they do.
But what if you want to add your own template or modify an existing one? Managing your own templates is important because your business domain and how you work determines to a large extent what is the common code you use all the time.
Don’t be tempted to say “It takes too long to create the template. In that time I could’ve typed the code myself.” Are you going to say that the next 50 times you have to type the same code? I always force myself to sacrifice the 2 minutes because I’ll save me 20 minutes in the long run.
How to add/edit a template
In the spirit of show, rather than tell, here’s a video that shows how to create a template to make it easier to add an additional case-statement to a switch-block. We want to add case blocks for IDLE and OFF for the enum EngineState.
A couple of notes on some of the fields we saw in the video:
Name: The shorter the better, because you want to type as little as possible to invoke it. But make it unique enough so you don’t get too many matches.
Context: Eclipse will only show the template in the list of available templates if it belongs to the right context. Eg. when editing JavaDoc’s, none of the Java statements templates will appear, only the Javadoc ones.
Description: Make it nice and… descriptive, stating what the template does. The short name may not always be enough to know this.
Pattern: You can mix normal Java code with template variables. I describe variables below.
Variables
You can use variables to make the template a bit smarter. Eclipse has a raft of built-in variables and although all variables are useful, some are more useful than others.
The example below (from the video) shows 2 variables: ${cursor} which tells Eclipse where to leave the cursor after cycling through all placeholders and ${value} which is a custom variable, ie. not built-in.
case ${value}:
${cursor}
break;
Keep the following in mind when using templates:
You can use the Tab key to move from one variable to another. No mouse or arrow keys required.
Custom variables don’t mean anything to Eclipse but they can be used later in the same template to refer to the same user-provided name. See the new template for an example of this.
You can also use an unnamed variable (${}) to signify a placeholder where the user should enter something but the variable isn’t used anywhere else.
Other variables can tell Eclipse to guess which field to use or to get documentation info (eg. current author).
Variables must be enclosed in ${} – don’t forget this.
Useful Variables
Here’s a rundown of the most useful variables. You can get a full list by pressing Ctrl+Space while editing a template.:
cursor – Tells Eclipse where the cursor will finally end up after you’ve edited all the other variables. Leave the cursor somewhere sensible like on a blank line so you can start typing immediately.
var – A list of variables in scope, the first guess being the last variable declared in the smallest scope. You can pass a type of limit the list to only variables of that type.
iterable, array, collection - A list of either iterables, arrays or collections in scope, starting with the last declared variable in the smallest scope. Nice for loops over an array/collection. iterable is sufficient for most situations as it covers both arrays and collections.
line_selection – Perfect for templates that wrap a block of selected code in a loop or some other construct. The for and while templates use these to allow you select code that will be placed in the loop. To use, select the code, then press Ctrl+Space twice to get Template Proposals (you may need more presses depending on how you’ve set up your proposal options.
import – A specific import you need generated together with the template. For example, a template that generates a log4j statement can also import log4j’s Logger. The import’s ignored if it already exists.
newName – A unique name for a variable based on the type you pass it. Eg. if you pass the type MultipleDocHandler, a variable with the name multipleDocHandler will be generated.
How to import/export a template
To make it easy to share templates, Eclipse allows you export a template so that someone else can import them. An XML file is produced which contains the template(s) you selected. I’ll be sharing some handy home-grown templates as XML files.
Here’s how to import/export a template
Go to Window > Preferences > Java > Editor > Templates
Select the templates you want. NB! The checkboxes don’t indicate what’s selected; they are used to enable/disable a template. A template is selected if the whole row in the table is selected, so use Ctrl+Left Click or method specific to your OS to multi-select templates.
Click Import… and choose the XML file you received. Or Export… and provide a filename.
for (int i = 0; i < arguments.length; i++) {
String argument = arguments[i];
// ... Do something with argument...
}
How many times have you typed out a similar for-loop, mistyped arguments the 2nd time, made a syntax error by forgetting a semicolon, etc, etc. Same goes for writing a main method or a try-catch block. Even typing an enhanced for-loop in the above example is slow.
To me they’re code zombies. Nobody likes them, everybody wants to get rid of them asap and just when you think you’ve killed one, it wakes up again and doesn’t stop… ever.
This is where templates bash in with modified shotguns and spiked baseball/cricket bats. You use templates to rid yourself of these code zombies, because life’s too short and fast to have to write long and slow code.
Why use templates?
Templates are an easy and fast way to add common, boilerplate code. They’re like bits of snippets, but usually shorter and more generic. Just type the name of the template, press a key and the code is magically inserted.
Existing code can also be affected by templates that support selections. For example, you can select a block of code and use the try template to wrap the entire block in a try-catch block.
Templates can also contain variables to make your generated code a bit smarter. Variables are like placeholders allowing you to easily edit various parts of the template.
How do you use templates?
Watch the video to get an idea of how templates work. It shows how to add a main method, with a for-loop that prints out all command line arguments using templates. Notice the smooth movement between variables (the green boxes):
Some notes:
To open a template, type the name then press Ctrl+Space, choose the template and press Enter.
The green boxes are template variables. You can use the Tab key to move from one variable to another. Forget about the mouse or arrow keys.
You can also wrap existing code in templates (eg. a for loop). Simply select the code, press Ctrl+Space twice and select the template.
How does this make you faster?
You did watch the video, right? In 20 seconds we wrote code that would normally take you around 40 to 50 seconds (and that’s if we don’t make any mistakes). The video is deliberately slowed down as well for clarity. We can improve that to 10-12 seconds for all that code.
So, 400% faster = time for 4 more cups of coffee a day = 100 x happier developer!
Templates have some smarts in them as well. The for-loop in the video immediately recommended the array args as it was the nearest collection/array in scope. This works 80% of the time, so that cuts down on some time as well.
Some useful templates to get you going
Eclipse has a lot of built-in templates. Have a look at them by going to Window > Preferences > Java > Editor > Templates.
For the lazy, here are some useful ones to speed things up a bit:
main – inserts a main method, arguments and all.
for – generates for-loops, eg. one with an index over an array or with a temporary variable; can wrap a selected block of code.
foreach – inserts an enhanced for-loop; can also wrap an existing selection in a for loop; can wrap a selected block of code.
try – produces a try-catch block with the default Exception and a todo to remind you to complete the exception block; can also wrap an existing selection in a try-catch; can wrap a selected block of code.
switch – adds a switch statement together with a case-block and default-block.
while – inserts a while-loop, optionally with an enumerator; can wrap a selected block of code.
Massive time savers already right there.
How do you create/edit a template
A very important topic, so I discuss this in a separate post.