Java vararg pass lambda and values

I am trying to combine 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: Log method cannot be applied to specified types; REQUIERED String, Object [] found: String, String, int, () β†’ "aaa", () β†’ 111 REASON: inconsistency varargs; The object is not a functional interface

Is it possible to pass both lambdas and values ​​to vararg?

+5
source share
3 answers

The problem is the error message

The object is not a functional interface

You can only create lambda for functional interfaces (one with one abstract method). An object is not an interface, and it has no abstract methods, so you cannot create a lambda of this type. What you can do is

 Log( "%s %d %s %d", "bbb", 222, (Supplier) () -> "aaa", (Supplier) () -> 111 ); 

Thus, the compiler knows which lambda you intended to implement.

For comparison, you can write the following, and this will behave differently in your method.

 Log( "%s %d %s %d", "bbb", 222, (Callable) () -> "aaa", (Callable) () -> 111 ); 
+4
source

The problem is that Object not @FunctionalInterface . In doing so, you can pass a simple anonymous example as follows:

 Log( "%s %d %s %d", "bbb", 222, new Supplier<String>() { @Override public String get() { return "aaa"; } }); 

This method can be used if you do not want to use unverified casts, which will lead to a compiler warning.

If you still want to use your lambda, this can be done as follows:

 Log( "%s %d %s %d", "bbb", 222, (Supplier<String>) () -> "aaa"); 
0
source

There is no way for the compiler to tell what type of functional interface is used to process it (unlike the first, since you determined that in the Type variable)

Therefore, the casting will fix the supplier. For instance. (not verified)

 Log( "%s %d %s %d", "bbb", 222, ((Supplier<String>)() -> "aaa"), ((Suplier<Integer>)() -> 111) ); 

Hope this points in the right direction.

0
source

Source: https://habr.com/ru/post/1258333/


All Articles