Статьи

Почти именованные аргументы метода в JDK 8

Иногда было бы очень хорошо иметь именованный параметр метода в Java, это вряд ли выглядит долгое время, но всегда есть другая небольшая работа, например, использование шаблона компоновщика для получения аналогичного поведения, которое устранит пробел немного. Мне пришло в голову, что используя лямбда-поддержку в JDK 8, вы можете получить что-то очень близкое без котельной пластины, требуемой некоторыми другими методами.

Итак, рассмотрим этот простой класс Facade, который представляет метод с переменным списком параметров. Обратите внимание на вариант метода, который принимает объект Consumer — это то, что мы собираемся вызвать с помощью лямбды позже.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package client;
 
import java.util.function.Consumer;
 
public class Facade {
 
    public static void invoke(Consumer<Parameter> op) {
 
        Parameter p = new Parameter();
        op.accept(new Parameter());
        invoke(p);       
    }
 
    public static void invoke(Parameter p) {
 
        // Defensive copy and validate
        p = p.clone();
        p.validate();
 
        // ...
    }
 
    public static class Parameter implements Cloneable {
        public String value1, value2, value3;
 
        public Parameter validate() {
            // ...
 
            return this;
        }
 
        public Parameter clone() {
            // We can use vanilla clone here, for more complicated mutable objects
            // you might need to perform a deeper copy
            try {
                return (Parameter) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }
    }
 
}

Поэтому, как только вы это сделаете, вы можете использовать лямбда-нотацию для вызова метода invoke с указанием всех параметров, которые вы считаете подходящими:

01
02
03
04
05
06
07
08
09
10
11
...
{
 
    public static void main(String[] args) {
 
        // Single parameter version
        Facade.invoke(p ->  p.value1="x" );
        // Multiple parameter version
        Facade.invoke(p -> { p.value1="x"; p.value2="y";});
    }
}

Конечно, орлиные глаза вашего узнают, что тот же шаблон, за исключением, конечно, Consumer метода, с более ранним JDK. Учитывая количество разработчиков Java, кто-то, вероятно, уже изобрел этот шаблон; но вы никогда не знаете, и если вы не запишите это, мысль, что это не произошло.

01
02
03
04
05
06
07
08
09
10
11
12
...
{
 
    public static void main(String[] args) {
 
        // Using an anonymous inner class pre JDK 8
        Facade.invoke(new Parameter() {{
            value1 = "x";
            value2 = "y";
        }});
    }
}