Java 在@FunctionInterface中处理VARAG的更干净的方法?

Java 在@FunctionInterface中处理VARAG的更干净的方法?,java,lambda,java-8,type-inference,Java,Lambda,Java 8,Type Inference,考虑这个接口: @FunctionalInterface public interface ThrowingFunction<T, R> { R tryApply(T t) throws Throwable; } 这个问题是由于。它可以使用LinkOption…作为参数 然而,编译器能够在这里“强制”方法引用。我想出的模仿这一点的唯一方法是彻头彻尾的恶作剧: @FunctionalInterface public interface ThrowingFunc

考虑这个接口:

@FunctionalInterface
public interface ThrowingFunction<T, R>
{
    R tryApply(T t)
        throws Throwable;
}
这个问题是由于。它可以使用
LinkOption…
作为参数

然而,编译器能够在这里“强制”方法引用。我想出的模仿这一点的唯一方法是彻头彻尾的恶作剧:

@FunctionalInterface
public interface ThrowingFunction<T, R>
{
    R tryApply(T t)
        throws Throwable;

    @FunctionalInterface
    interface WithVarags<T, V, R>
        extends ThrowingFunction<T, R>
    {
        R tryApplyWithVarargs(T t, V... ignored)
            throws Throwable;

        @Override
        default R tryApply(T t)
            throws Throwable
        {
            return tryApplyWithVarargs(t);
        }
    }
}

有没有更干净的方法?也就是说,在这种情况下,我可以“喜欢编译器”吗?

您可以在实例中指定
包装器的类型

new Wrapper<Path, Path>(Path::toRealPath);
newwrapper(路径::toRealPath);

Wrapper=newwrapper(路径::toRealPath);
我认为这与瓦拉格家族无关。通过指定类型,您还可以告诉编译器“忽略”varargs参数


注意,我看到您也可以“忽略”相同函数的返回类型:

ThrowingBiConsumer<Path, LinkOption[]> biConsumer =  Path::toRealPath;
new Wrapper<Path, LinkOption[]>(Path::toRealPath);


public interface ThrowingBiConsumer<T, U> {
    void accept(T t, U u) throws Throwable;
}
ThrowingBiConsumer-biConsumer=Path::toRealPath;
新包装器(路径::toRealPath);
通过双消费者的公共接口{
无效接受(T,U)抛出可丢弃的;
}

如果你想像编译器那样做,你必须
新建包装((p)->((Path)p).toRealPath(newlinkoption[0])。如果你能更多地解释你最终想要得到什么,也许解决起来会更容易。您希望通过Path::toRealPath函数实现什么?我试图追溯您的解决方法,但是,它对我不起作用,它实际上使事情变得更糟,因为即使显式指定类型参数也不起作用。毕竟,没有任何目标类型是很少见的;请注意,在您的问题中,您甚至没有为
包装器
实例化指定菱形运算符。实际上,您可能会有一个目标类型,或者帮助编译器使用
newwrapper((路径p)->p.toRealPath())
,但是,它似乎是一个编译器缺陷,无法正确推断方法引用中的varargs类型。这是我不想做的。看;现在我不需要。我想要方法的结果,因此,
消费者
也不是一个选项……是的,我知道这只是一个旁注。
@FunctionalInterface
public interface ThrowingFunction<T, R>
{
    R tryApply(T t)
        throws Throwable;

    @FunctionalInterface
    interface WithVarags<T, V, R>
        extends ThrowingFunction<T, R>
    {
        R tryApplyWithVarargs(T t, V... ignored)
            throws Throwable;

        @Override
        default R tryApply(T t)
            throws Throwable
        {
            return tryApplyWithVarargs(t);
        }
    }
}
public <V> Wrapper(
    final ThrowingFunction.WithVarags<T, V, R> function)
{
    this.function = function;
}
new Wrapper<Path, Path>(Path::toRealPath);
Wrapper<Path, Path> wrapper = new Wrapper<>(Path::toRealPath);
ThrowingBiConsumer<Path, LinkOption[]> biConsumer =  Path::toRealPath;
new Wrapper<Path, LinkOption[]>(Path::toRealPath);


public interface ThrowingBiConsumer<T, U> {
    void accept(T t, U u) throws Throwable;
}