Java vararg pass lambda and values
I'm trying to unite lambdas and simple values in varag.
public static void Log(String format, Object ... args) {
final Object[] fmt = new Object[ args.length ];
for(int i = 0; i < args.length; i++)
fmt[i] = args[i] instanceof Supplier ?
( (Supplier) args[i] ).get() :
args[i];
final String s = String.format( format, fmt );
System.err.println( s );
}
final Supplier
s = () -> "aaa",
d = () -> 111;
Log( "%s %d %s %d", "bbb", 222, s, d ); // OK, OUTPUT: bbb 222 aaa 111
Log( "%s %d %s %d", "bbb", 222, () -> "aaa", () -> 111 ); // COMPILE FAIL
ERROR: method Log cannot be applied to given types; REQUIERED String,Object[] found: String,String,int,()->"aaa",()->111 REASON: varargs mismatch; Object is not a functional interface
Is it possible to pass both lambdas and values to vararg?
The problem is in the error message
Object is not a functional interface
You can only create a lambda for a functional interfaces (one with exactly one abstract method) Object is not an interface and it doesn't have any abstract methods so you can't create a lambda of this type. What you can do is
Log( "%s %d %s %d", "bbb", 222, (Supplier) () -> "aaa", (Supplier) () -> 111 );
This way the compiler knows what sort of lambda you intended to implement.
By comparison you could write the following and this would behave differently in your method.
Log( "%s %d %s %d", "bbb", 222, (Callable) () -> "aaa", (Callable) () -> 111 );
For the compiler there is no way to tell what type of functional interface is used when you delcare them (unlike the first one, since you defined that in the variableType)
So a fix would be casting the supplier. Eg (not tested)
Log( "%s %d %s %d", "bbb", 222, ((Supplier<String>)() -> "aaa"), ((Suplier<Integer>)() -> 111) );
Hope this points in the right direction.
The problem is that Object
is not a @FunctionalInterface
. That being said you can pass a simple anonymous instance like this:
Log( "%s %d %s %d", "bbb", 222, new Supplier<String>() {
@Override
public String get() {
return "aaa";
}
});
This method can be used if you don't want to use unchecked casts which will result in a compiler warning.
If you still want to cast your lambda it can be done this way:
Log( "%s %d %s %d", "bbb", 222, (Supplier<String>) () -> "aaa");
链接地址: http://www.djcxy.com/p/78958.html
下一篇: Java可变参数传递lambda和值