Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

double colon assignment on method with two parameters

I am using lamdbas so I can consistently set the properties of a ModelObject according to the values I can retrieve from three different objects. The code works like this:

public class Processor {

    private void bar(Setter setter, MyClass myObject) {
        String variable = myObject.getStringByABunchOfMethods();
        setter.setVariable(variable);
    }

    protected void foo(...) {
        ...
        bar(value -> model.setA(CONSTANT, value), aObject);
        bar(value -> model.setB(value), bObject);
        bar(value -> model.setC(value), cObject);
        ...
    }

    private interface Setter {
        public void setVariable(String string);
    }

}

public interface IModel {
    public void setA(String arg0, String arg1);
    public void setB(String arg0);
    public void setC(String arg0);
}

I have read here that it is possible to rewrite bar(value -> model.setB(value), bObject); to bar(model::setB, bObject). I think this looks better and more concise, but I haven't found a way to rewrite the setA method to a double :: notation. Can anyone tell me if this is possible, and if so: how is this possible?

like image 592
ivospijker Avatar asked Jan 17 '17 13:01

ivospijker


2 Answers

from https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html and https://www.codementor.io/eh3rrera/tutorials/using-java-8-method-reference-du10866vx

There would be 4 different kinds of method references. The corresponding lambda and method reference:

  • (args) -> Class.staticMethod(args), Class::staticMethod
  • (obj, args) -> obj.instanceMethod(args), ObjectType::instanceMethod
  • (args) -> obj.instanceMethod(args), obj::instanceMethod
  • (args) -> new ClassName(args), ClassName::new

The lambda value -> model.setA(CONSTANT, value) does not correspond with any of the lambdas above, so it is not possible to rewrite it as a method reference.

like image 54
toongeorges Avatar answered Oct 30 '22 21:10

toongeorges


To use the double colon notation, the method that you're referencing must have the same signature as the required method. So you can't use :: unless you change your IModel:

You can add an overload of setA in IModel:

default void setA(String arg0) {
    setA(CONSTANT, arg0);
}

Then, you can reference that overload:

bar(model::setA, aObject);

.

like image 43
Sweeper Avatar answered Oct 30 '22 20:10

Sweeper