Java可变参数传递lambda和值

我试图在varag中联合lambdas和简单的值。

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

错误:方法日志不能应用于给定的类型; REQUIERED String,Object [] found:String,String,int,() - >“aaa”,() - > 111原因:可变参数不匹配; 对象不是一个功能接口

是否有可能将lambda表达式和值传递给vararg?


问题出在错误信息中

对象不是一个功能接口

你只能为一个函数接口(一个只有一个抽象方法)创建一个lambda。Object不是一个接口,它没有任何抽象方法,所以你不能创建这种类型的lambda。 你可以做的是

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

这样编译器就知道你打算实现哪种lambda。

通过比较,你可以写出以下内容,这在你的方法中会有不同的表现。

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

对于编译器来说,当你对它们进行删除时,没有办法知道使用了哪种类型的功能接口(不像第一种,因为你在variableType中定义了这个接口)

所以一个解决方案就是施放供应商。 例如(未测试)

Log( "%s %d %s %d", "bbb", 222, ((Supplier<String>)() -> "aaa"), ((Suplier<Integer>)() -> 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");
链接地址: http://www.djcxy.com/p/78957.html

上一篇: Java vararg pass lambda and values

下一篇: Default empty case for varargs