Named Parameter Idiom in Java

Named Parameter idiom in Java

The best Java idiom I've seem for simulating keyword arguments in constructors is the Builder pattern, described in Effective Java 2nd Edition.

The basic idea is to have a Builder class that has setters (but usually not getters) for the different constructor parameters. There's also a build() method. The Builder class is often a (static) nested class of the class that it's used to build. The outer class's constructor is often private.

The end result looks something like:

public class Foo {
public static class Builder {
public Foo build() {
return new Foo(this);
}

public Builder setSize(int size) {
this.size = size;
return this;
}

public Builder setColor(Color color) {
this.color = color;
return this;
}

public Builder setName(String name) {
this.name = name;
return this;
}

// you can set defaults for these here
private int size;
private Color color;
private String name;
}

public static Builder builder() {
return new Builder();
}

private Foo(Builder builder) {
size = builder.size;
color = builder.color;
name = builder.name;
}

private final int size;
private final Color color;
private final String name;

// The rest of Foo goes here...
}

To create an instance of Foo you then write something like:

Foo foo = Foo.builder()
.setColor(red)
.setName("Fred")
.setSize(42)
.build();

The main caveats are:

  1. Setting up the pattern is pretty verbose (as you can see). Probably not worth it except for classes you plan on instantiating in many places.
  2. There's no compile-time checking that all of the parameters have been specified exactly once. You can add runtime checks, or you can use this only for optional parameters and make required parameters normal parameters to either Foo or the Builder's constructor. (People generally don't worry about the case where the same parameter is being set multiple times.)

You may also want to check out this blog post (not by me).

Java 8 named parameter passing?

In the video you can later see the parameters go back to normal form, so it's some sort of IDE plugin/tool/macro (looks like IntelliJ IDEA, which has a lot of these) to display it in that form.

I can definitely see the advantage in a demonstration situation like that, so while it's not available in the current Java version, who knows what future will bring.

How can I get named parameters in Java in static methods?

There is no such thing as named parameters in Java.

There are workarounds and there have been submissions in Project Coin but they were rejected. Sun is well aware that there is a demand but, so far, they have rejected any such language change.

Using Maps as suggested above is a possibility but unless all your arguments have the same type, it is cumbersome. And it's not really efficient either.

write parameter names in method call

This syntax is not supported in Java.

It can be argued that it is not needed as the order of parameters in function signatures are strongly enforced in Java.

Also, you should be mindful that function overloading is supported in Java, where multiple functions may have the same name but different number of parameters. This means you cannot omit any specified input, in order to avoid calling another overloaded function unintentionally.

Using Named Parameter in native SQL query with Spring Data JPA

You use variable COL_1_1001 in your query but do not provide it. You have to add an argument annotated with @Param so the value can be injected into query.

Change:

@Query(value="SELECT COL_1"
+ ",COL_2"
+ ",COL_3"
+ "FROM TABLE_A"
+ "WHERE COL_1 = :COL_1_1001", nativeQuery = true)
List<Entity> getEntityDetails();

to:

@Query(value="SELECT COL_1"
+ ",COL_2"
+ ",COL_3"
+ "FROM TABLE_A"
+ "WHERE COL_1 = :col", nativeQuery = true)
List<Entity> getEntityDetails(@Param("col") String col); // it may not be a string - use the actual tyle of COL_1

For more info look into Spring Data documentation

Clever way for a method to accept any combination of unique objects as parameters?

No, the language specification mentions no such easy way.

You can always pass Objects and perform type checks yourself, but that's a wrong approach.

Java does not allow named parameters (ways around it in link).



Related Topics



Leave a reply



Submit