为了账号安全,请及时绑定邮箱和手机立即绑定

如何为泛型方法编写简洁的闭包?

如何为泛型方法编写简洁的闭包?

幕布斯7119047 2021-10-27 16:28:40
我想编写一个具有泛型方法的功能性非泛型接口的实现。实现需要是内联闭包和简洁的。作为一个简化的例子@FunctionalInterface interface Fn {    <R> R fn(R arg);}public class Scratch {    Fn id = arg -> arg;    //Fn nul = arg -> null;    //Fn requiresNonNull = ...}这使/Scratch.java:5: error: incompatible types: invalid functional descriptor for lambda expression    Fn id = arg -> arg;            ^    method <R>(R)R in interface Fn is generic  where R is a type-variable:    R extends Object declared in method <R>fn(R)1 error(实际上,该参数将是一个具有返回类型为 的方法的通用接口R。)有没有一种解决方法而不必回到匿名内部类的冗长之处?有一个明显的类似的问题,“不能转换功能界面与通用方法引入lambda表达式”,但是从使用一个被称为类型参数茎Integer,而不是其他传统一样T,和乔恩斯基特的接受的答案说,他不知道解决我的问题。还有一个很长的讨论,“功能接口混淆”,没有回答这个问题。不可能是“这里最好使用冗长的匿名内部类”,对吗?
查看完整描述

2 回答

?
芜湖不芜

TA贡献1796条经验 获得超7个赞

泛型 lambda 不合法,但泛型方法引用是合法的。您可以通过创建辅助方法来减少匿名类的冗长:


public class Scratch {

    Fn id = Scratch::id;

    Fn nul = Scratch::nul;

    Fn requiresNotNull = Objects::requireNonNull;


    private static <R> R id(R arg) {

        return arg;

    }


    private static <R> R nul(R arg) {

        return null;

    }

}


查看完整回答
反对 回复 2021-10-27
?
慕的地10843

TA贡献1785条经验 获得超8个赞

经过大量实验和间接操作后,我有了一个解决方案。我在命名方面不太成功。

这是想法

  • 函数式接口和单个抽象方法都没有类型参数。

  • 函数式接口接收具有类型参数但在方法参数中使用通配符的使用者。

  • 消费者只是一块内部gubbins,但它确实具有该类型参数。它用于在执行通过封闭函数返回时存储结果。

  • 消费者本身接收一个包含实际业务功能实例的功能接口,该实例属于参数化类型。

  • 有一个默认方法可以将事物联系在一起,包括创建使用者。

清除?【修辞】

所以,而不是能够写

Fn id = arg -> arg;

我们至少可以写

Fn id = q -> q.q(arg -> arg);

这是一个 lambda lambda 工厂。

我们似乎语法用完了,不能写类似的东西

Fn id = Fn.Consumer::q(arg -> arg); // not valid syntax!

总而言之(有一个主要表明我没有作弊)

import java.util.concurrent.atomic.*;


@FunctionalInterface interface Fn {

    interface Instance<R> {

        R fn(R arg);

    }

    interface Consumer<R> {

       void q(Instance<R> gn);

    }


    void consume(Consumer<?> consumer);


    default <R> R fn(R arg) {

        AtomicReference<R> result = new AtomicReference<>();

        this.consume((Instance<R> instance) -> { result.set(instance.fn(arg)); });

        return result.get();

    }

}


public interface Scratch {

    Fn id = q -> q.q(arg -> arg);

    Fn nul = q -> q.q(arg -> null);


    public static void main(String[] args) {

        String idStr = id.fn("cruel");

        String nulStr = nul.fn("cruel");


        System.err.println(idStr);

        System.err.println(nulStr);

    }

}

我认为我没有利用类型系统中的任何缺陷。


(我可能应该在问题中添加一个更复杂的示例,以说明您为什么要这样做。)


查看完整回答
反对 回复 2021-10-27
  • 2 回答
  • 0 关注
  • 162 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信