Named Parameters in Java
I lately came across some code that looked like this:
-
o.doSomething1(
-
"Alfred E. Neumann",
-
"http://blog.schauderhaft.de",
-
42,
-
"c:\\temp\\x.txt",
-
23);
Things were actually worse since there where about 20 or 30 such calls and there was no hint what so ever to the difference in meaning of the various literals.
Why is so bad? The problem here is that a user of the method doSomething1 might accidently call it with
-
o.doSomething1(
-
"Alfred E. Neumann",
-
"c:\\temp\\x.txt",
-
42,
-
"http://blog.schauderhaft.de",
-
23);
There is no hint that something went wrong. It will compile. And if you are lucky it will blow up once the call executes. But maybe the application will just behave really strange.
Some languages have a feature called named parameters that allows a syntax like this:
-
o.doSomething(
-
name = "Alfred E. Neumann",
-
link = "http://blog.schauderhaft.de",
-
ultimateAnswer = 42,
-
tempFile = "c:\\temp\\x.txt",
-
zip = 23);
Unfortunately Java is not among these languages. But as so often we can trick Java into actually helping us if we are willing to invest in some extra typing.
How about this?
-
o.doSomething2(
-
name("Alfred E. Neumann"),
-
link("http://blog.schauderhaft.de"),
-
ultimateAnswer(42),
-
tempFile("c:\\temp\\x.txt"),
-
zip(23));
It works like this: For every parameter there is a little class:
-
public class Name {
-
public final String name;
-
public Name(String n) {
-
name = n;
-
}
-
}
And a static method:
-
static Name name(String n) {
-
return new Name(n);
-
}
While this is a lot of typing, it gives you some type safety and the equivalence of named parameters. It might also be the first step toward value objects in your code, after all, when you have these values wrapped, why would you unwrap them before you have to? In that case you should implement hashcode and equals.
There are alternative ways to get similar effects. We’ll look at tehm in another blog post.






What about performance ? In your example, you end up with:
– 5 extra object instances
– 5 extra method calls for wrapping parameters
– at least 5 extra method calls for unwrapping them
You better solve by using a good IDE that displays the parameter name as you type it…
Reasonably popular approach.
http://blog.joda.org/2008/11/java-language-change-unique-identifier_1824.html
Only drawback – too much objects;
usually unnoticeable in enterprise environment.
I hope JEP-104 (JSR-305 + JSR-308) “annotations everywhere” is out;
it will teach us to solve it cheaper,
in common way with (JSR-330 + JSR-299) “CDI”:
void Obj#doSomething1(
@Name String,
@Url String,
int x,
@Path String,
int);
o.doSomething1(
@Name “Alfred E. Neumann”, //compile-time check
@Url “http://blog.schauderhaft.de”,
42,
@Path “c:\\temp\\x.txt”,
23);
[...] Named Parameters in Java (Schauderhaft) [...]
interesting! i like this little dsl
@julien: it’s always the same… how much performance impact has this design? it depends on the project. performance can be problem, but maintenance is more important.
I agree that named parameters are nice to have. But in your example and i guess most methods like that, I think the real problem is not the absence of named parameters. The problem is, that there are _too many_ parameters, e.g. because the method does too many things. Clearly named methods, that follow the single responsibility principle taking 0 to 2 parameters, usually are fine without named parameters.
Yes and no.
I agree: there is probably a concept hiding behind all these strings, that needs to get out.
But: It is often not at all clear what that concept might be. Or introducing the concept might trigger a huge refactoring not possible and that point in time. Such ‘named parameter’ are one more option to move in a good direction.
If their usage ‘leaks’ further they might actually evolve into such concepts.
A method with five arguments. Yikes! Put the arguments into a class of its own and use a fluent interface, like so:
o.doSomething(MyArguments.start().name(“Alfred E. Neumann”).
link(“http://blog.schauderhaft.de”).
ultimateAnswer(42).
tempFile(“c:\\temp\\x.txt”).
zip(23).end());
Using a value class for concepts like name or link is of course still recommended. The code in the builder class for MyArguments could look like this:
public MyArguments.Builder name(String name) {
this.name = new Name(name);
return this;
}
usually named parameters usually means you need not preserve the order
you can’t doSomething2 ( link(“www.yahoo.com”, name(“ass”) )
e.g.
Builder pattern in java is preferred way of solving it like object.
setName(“Alfred E. Neumann”) .setLink(“http://blog.schauderhaft.de) .setUltimateAnswer(42) .setTempFile(“c:\\temp\\x.txt”) .setZip(23);