当前位置: 首页 > 知识库问答 >
问题:

Kotlin:参数化类型的构造函数引用出现编译错误

太叔灿
2023-03-14

我试图用Kotlin编写如下Java代码:

interface Provider {
}

class ProviderImpl1 implements Provider {
}

class ProviderImpl2 implements Provider {
}

enum Providers {
    ONE(ProviderImpl1::new),
    TWO(ProviderImpl2::new);

    private final Supplier<Provider> supplier;

    Providers(Supplier<Provider> supplier) {
        this.supplier = supplier;
    }

    public Provider provider() {
        return supplier.get();
    }
}

此代码编译并正确工作:Providers。ONE生成一个ProviderIM1Providers的实例。TWO给出一个ProviderIM2的实例。

以下是我在科特林的成就:

interface Provider {
}

class ProviderImpl1 : Provider {
}

class ProviderImpl2: Provider {
}

enum class Providers(private val factory: Supplier<Provider>) {
    ONE(Supplier{ ProviderImpl1() }),
    TWO(Supplier{ ProviderImpl2() });

    fun provider(): Provider = factory.get()
}

它可以工作,但在Java中,我可以在枚举构造函数中使用构造函数引用。当我尝试在科特林做同样的事情时,也就是

ONE( ::ProviderImpl1 ),

我发现以下编译错误:

类型不匹配:推断的类型为KFunction0,但应为供应商

没有显式类型的lambda也不起作用:

ONE( ::ProviderImpl1 )

给予

类型不匹配:推断类型是()-

问题是:静态编程语言规范是否禁止这样做(如果是,为什么,因为Java似乎在处理它),或者这只是当前静态编程语言编译器的暂时缺陷?

我的构建。gradle有以下几点

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.2.61'
}

静态编程语言版本由Idea(在项目设置中)显示为1.2。


共有2个答案

邵刚洁
2023-03-14
匿名用户

你可以使用kotlin。反映KFunction0与编译错误建议的类似,而不是java。util。作用供应商,然后您可以使用方法参考。

例:

import kotlin.reflect.KFunction0

interface Provider {
}

class ProviderImpl1 : Provider {
}

class ProviderImpl2: Provider {
}

enum class Providers(private val factory: KFunction0<Provider>) {
    ONE(::ProviderImpl1),
    TWO(::ProviderImpl2);

    fun provider(): Provider = factory.call()
}

在这种情况下,错误消息表明它需要一个接口kotlin。反映KFunction0不是java。util。作用供应商,因此不禁止在此构造函数中使用方法引用。你可以使用它,你只需要使用预期的接口。

冯泓
2023-03-14

如果您将供应商更改为lambda,这可以在Kotlin很好地实现。。。

interface Provider
class ProviderImpl1 : Provider
class ProviderImpl2 : Provider

enum class Providers(private val supplier: () -> Provider) {
    ONE({ ProviderImpl1() }),
    TWO({ ProviderImpl2() });

    fun provider(): Provider = supplier.invoke()
}

这里的变化是交一个函数,它返回一个提供者实例(本质上就是提供者)。这很好,因为如果在将来,您的提供程序实现在构建时需要某种配置,那么这个lambda可以处理这个问题。

如果你的提供者是无状态的,你可以通过改变提供者来逃脱。provider()转换为val,每个枚举类型只创建一次。

 类似资料:
  • 我是新手。我想在Person类驱动的Employee类中添加age参数。我怎么能在科特林做到?! 我的错误是这样的: 为什么不能在员工构造函数中使用var或val?!我犯了什么错误?

  • 我有一个有两个构造函数的类。 有一个具有两个构造函数的类Sample。需要在Sample类中实例化另外三个类(ClassOne,ClassTwo和ClassIII)。所有三个类都包含默认和参数化构造函数。如果调用了Sample类的默认构造函数,则应调用ClassOne,ClassTwo和ClassIII的默认辅助构造函数。如果调用Samples参数化构造函数,则调用ClassOne、ClassII

  • 问题内容: 行给出了编译错误。 为何不允许这样做的任何特定原因?如何使用数组常量初始化String数组? 编辑:谢谢大家的回答。现在,我很清楚什么是允许的,什么是不允许的。但是我能问你 为什么 不允许这样做吗? 仔细搜索一下之后,我发现了这个链接,在其中,被告知像这样的编码使编译器不明确- 宠物应该是String数组还是Objects数组。但是,从声明中可以很好地看出它是一个String数组,对吗

  • 以下代码使用Clang(3.9.1测试)和GCC(6.3测试)编译,如此链接所示:https://godbolt.org/g/kO1nBa.但是,MSVC(19.00.24215.1测试)无法编译它: 错误C2131:表达式未计算为常量 注意:失败是由赋值操作的计算引起的 注意:在评估'ExtraResidentsValueWitnessTable::ExtraResidentsValueWitn

  • 我有以下代码: 我不希望字段ui有一个getter,但是kotlin在默认情况下会生成它,因为它是构造函数中定义的val。 在properties and fields文档中,我发现我可以用以下代码生成一个私有getter 但我在构造函数定义中找不到这样做的方法

  • 我有一个kotlin库项目,并使用进行测试。在我的测试中,我尝试使用以下函数: 是正确的行为吗?