I defined one FunctionalInterface
as below:
@FunctionalInterface
public interface BaseAction {
public void execute(final DataObj dataObj) throws Exception;
}
Then, a class implementing the same as follows:
public class Select implements BaseAction{
@Override
public void execute(final DataObj dataObj) {
//some operations on dataObj here..
}
}
And when I tried instantiating the class Select
using syntax prior to Java 8
, compiles for me, as follows:
public BaseAction getAction(final String action) {
switch (action) {
case "SELECT": return new Select(); //Works
}
return null;
}
But, when I tried instantiating it using Java 8
syntax, IDE starts complaining me "The type Select does not define Select(DataObj) that is applicable here"
,
public BaseAction getAction(final String action) {
switch (action) {
case "SELECT": return Select::new; //Compile error here..
}
return null;
}
Any idea how can I fix it?
What you're using is not "the Java 8 syntax for creating an object". You're using a reference to the constructor, so in a way the difference between your two pieces of code is the same as between
someObject.toString()
and
someObject.toString
The first one instantiates a new object, the second one points to the thing used to instantiate the new object, but doesn't call it (the more precise analogy would be to
someObject::toString
, by the way).If all you want to do is to instantiate a
Select
object, then just keep using the "old" code, it's exactly how you'll do it in Java 8.The new syntax is useful if you want to pass the specific constructor to use to some piece of code that wants to be agnostic to which constructor/type is used.
You could do something like that:
And call it like this:
The method reference
Select::new
is a reference to a constructor, and it doesn't match the required functional interface signature, taking aDataObj
parameter and returningvoid
.You'll need a
Select
reference to create the method reference, but it must refer to theexecute
method. This should work:As you've noted,
return new Select();
works, and it's less verbose. I would still use this, but the method reference above should work.