Java 可变参数传递 lambda 和值
Java vararg pass lambda and values
我正在尝试在 varag 中结合 lambda 和简单值。
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
错误:无法将方法 Log 应用于给定类型;所需字符串,对象 [] 找到:字符串,字符串,整数,()->"aaa",()->111 原因:可变参数不匹配;对象不是功能接口
是否可以将 lambda 和值都传递给可变参数?
问题出在错误信息中
Object is not a functional interface
您只能为功能接口(只有一个抽象方法)创建 lambda。对象不是接口,它没有任何抽象方法,因此您不能创建这种类型的 lambda。你能做的是
Log( "%s %d %s %d", "bbb", 222, (Supplier) () -> "aaa", (Supplier) () -> 111 );
这样编译器就知道您打算实现哪种 lambda。
相比之下,您可以编写以下内容,这在您的方法中的行为会有所不同。
Log( "%s %d %s %d", "bbb", 222, (Callable) () -> "aaa", (Callable) () -> 111 );
问题是 Object
不是 @FunctionalInterface
。话虽如此,您可以像这样传递一个简单的匿名实例:
Log( "%s %d %s %d", "bbb", 222, new Supplier<String>() {
@Override
public String get() {
return "aaa";
}
});
如果您不想使用会导致编译器警告的未经检查的强制转换,可以使用此方法。
如果你仍然想转换你的 lambda,可以这样做:
Log( "%s %d %s %d", "bbb", 222, (Supplier<String>) () -> "aaa");
对于编译器,当你 delcare 它们时,无法判断使用的是什么类型的功能接口(不像第一个,因为你在 variableType 中定义了它)
所以解决办法是铸造供应商。例如。 (未测试)
Log( "%s %d %s %d", "bbb", 222, ((Supplier<String>)() -> "aaa"), ((Suplier<Integer>)() -> 111) );
希望这指向正确的方向。
我正在尝试在 varag 中结合 lambda 和简单值。
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
错误:无法将方法 Log 应用于给定类型;所需字符串,对象 [] 找到:字符串,字符串,整数,()->"aaa",()->111 原因:可变参数不匹配;对象不是功能接口
是否可以将 lambda 和值都传递给可变参数?
问题出在错误信息中
Object is not a functional interface
您只能为功能接口(只有一个抽象方法)创建 lambda。对象不是接口,它没有任何抽象方法,因此您不能创建这种类型的 lambda。你能做的是
Log( "%s %d %s %d", "bbb", 222, (Supplier) () -> "aaa", (Supplier) () -> 111 );
这样编译器就知道您打算实现哪种 lambda。
相比之下,您可以编写以下内容,这在您的方法中的行为会有所不同。
Log( "%s %d %s %d", "bbb", 222, (Callable) () -> "aaa", (Callable) () -> 111 );
问题是 Object
不是 @FunctionalInterface
。话虽如此,您可以像这样传递一个简单的匿名实例:
Log( "%s %d %s %d", "bbb", 222, new Supplier<String>() {
@Override
public String get() {
return "aaa";
}
});
如果您不想使用会导致编译器警告的未经检查的强制转换,可以使用此方法。
如果你仍然想转换你的 lambda,可以这样做:
Log( "%s %d %s %d", "bbb", 222, (Supplier<String>) () -> "aaa");
对于编译器,当你 delcare 它们时,无法判断使用的是什么类型的功能接口(不像第一个,因为你在 variableType 中定义了它)
所以解决办法是铸造供应商。例如。 (未测试)
Log( "%s %d %s %d", "bbb", 222, ((Supplier<String>)() -> "aaa"), ((Suplier<Integer>)() -> 111) );
希望这指向正确的方向。