java - 使用反射为泛型类型变量生成 lambda 类

标签 java generics lambda java-8

我正在尝试将 Java 接口(interface)用作 D 类型的某些高级包装器中的混入。

interface WrapsD {
    D getWrapped();
}

interface FeatureA extends WrapsD {
    default ...
}

interface FeatureB extends WrapsD  {
    default ...
}

abstract class DWrapperFactory<T extends WrapsD> {
    protected T doWrap(D d) {
        return () -> d; // <- does not work
    }
}

interface FeatureAB extends FeatureA, FeatureB {
}

class ProducingDWithFeatureAB extends DWrapperFactory<FeatureAB> {
    protected FeatureAB doWrap(D d) {
        return () -> d; // <- has to repeat this
    }
}

ProducingDWithFeatureAB 所示,即使主体相同,也必须在每个子类中实现 doWrap。 (另一个例子说明了为什么 Java 泛型真的被破坏了。)

由于出于其他原因我已经需要创建像 ProducingDWithFeatureAB 这样的具体类,并且 JRE 中存在用于合成 lambda 类的代码,因此应该可以只编写一次 doWrap使用反射。我想知道如何做到这一点。

(doWrap以前是使用实现接口(interface)的匿名内部类实现的,这就更biolderplate了。)

最佳答案

这与泛型无关;您的通用示例只是混淆了真正的问题。

问题的核心在于:lambda 表达式需要一个作为函数式接口(interface)的目标类型,并且编译器必须静态地知道该目标类型。您的代码没有提供。例如,出于同样的原因,以下代码会得到同样的错误:

Object o = arg -> expr;

在这里,Object 不是函数式接口(interface),lambda 表达式只能在类型为(兼容的)函数式接口(interface)的上下文中使用。

泛型的使用让它变得更加困惑(我想你自己也对泛型的工作原理感到困惑),但最终这将是触底的地方。

关于java - 使用反射为泛型类型变量生成 lambda 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37007108/

相关文章:

java - 具有 hibernate 标准的 COALESCE 函数

java - ElasticSearch Lucene 使用 Java API 进行全文搜索

c# - 通用集合继承

c# - 比较两个自定义 LIST 对象

c++ - 定义 lambda 的一般准则

java - 用于批量发送电子邮件的 jars

java - 如何使用DriverManager模块化后打开jar内的HSQLDB资源(只读)?

Java:抽象泛型类和方法重载顺序

使用 Kotlin 中的 Guava 的 toImmutableSortedMap 收集器时出现泛型错误

java - 简化叉积 foreach 循环 - 也许使用 Lambda?