如何在Java 8中创建一个lambda表达式来定义toString?

aal*_*lku 7 java lambda java-8

我不希望有一个正常的lambda实现一个方法,并重新定义它的toString作为一个附加值.我希望lambda表达式只实现toString方法.我知道我的表达不是很好,但我相信你会用这个例子来理解我.

public class LambdaToStringTest {

    public interface ToStringInterface {
        public abstract String toString();
    }

    public static void main(String[] args) {
        print("TRACE: %s", (ToStringInterface)()->someComputation()); // <<-- ERROR: The target type of this expression must be a functional interface
    }

    private static void print(String format, Object... args) {
        System.out.println(String.format(format, args));
    }

}
Run Code Online (Sandbox Code Playgroud)

如果我更改方法的名称但它不会覆盖toString,则编译,因此print方法不会打印预期的内容.

这是尝试定义一个日志子系统,该子系统仅在需要时(当它真的要打印时)评估lambda,但与非lambda参数兼容.我知道其他方法来实现它,但我想知道为什么我不能这样做,如果有一个解决方法或我做错了什么,

fge*_*fge 5

简短的回答,你不能.@FunctionalInterfaces不能用于"覆盖"方法Object.

Formattable但是,您可以使用虚拟扩展方法实现.注意:下面的代码是UNTESTED:

@FunctionalInterface
public interface ToStringInterface
    extends Formattable
{
    String asString();

    @Override
    default void formatTo(Formatter formatter, int flags, int width, int precision)
    {
        formatter.format("%s", this);
        // Or maybe even better:
        formatter.out().append(this.asString());
    }
}
Run Code Online (Sandbox Code Playgroud)

我建议使用此解决方案,因为您正在使用此解决方案String.format().

或者您可以定义自己的界面.甚至写了这个接口,它调用的包装.toString().asString().选择很多.


小智 5

static <X,Y> Function<X,Y> withName(Function<X,Y> func, String name) {
    return new Function<X, Y>() {
        @Override
        public Y apply(X x) {
            return func.apply(x);
        }

        @Override
        public String toString() {
            return name;
        }
    }; 
}

/* Predicate, BiFunction, ... */

{// using
    myFunction(
        withName(a->a+1, "add one"), 
        withName((a,b)->a+b, "sum")
    );
}
Run Code Online (Sandbox Code Playgroud)