有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java中使用Kotlin值类

我们有两个项目,KotlinOne发布了一个由java导入的包

在kotlin中,是一个值类,如

@JvmInline
value class CountryId(private val id: UUID) {
    override fun toString(): String = id.toString()
    companion object { fun empty(): CountryId = CountryId(EMPTY_UUID) }
}

在java中,我们无法看到构造函数,也无法实际实例化此类。我还尝试在科特林创建一个工厂来创建它们

class IdentifierFactory 
{
    companion object {
        fun buildString(): String {
            return "hello"
        }

        fun buildCountry(): CountryId {
            return CountryId.empty()
        }
    }
}

在java中,我可以调用IdentifierFactory.Companion.buildString(),它会工作,但IdentifierFactory.Companion.buildCountry()甚至不存在

Java真的有这么糟糕的值类吗

另外,我也尝试过@JvmStatic,但没有成功

pps。如果我从java端反编译kotlin字节码,并获得CountryId。反编译。java,这就是构造函数的样子

// $FF: synthetic method
private CountryId(UUID id) {
    Intrinsics.checkNotNullParameter(id, "id");
    super();
    this.id = id;
}

购买力平价。Kotlin 1.5.21和Java 12


共 (1) 个答案

  1. # 1 楼答案

    Is Java really this awful with Value classes?

    值类是Kotlin功能。他们基本上是糖,以允许更多的类型安全(在Kotlin!)同时通过取消绑定内部值来减少分配。字节码中存在CountryId类这一事实主要是因为某些实例在某些情况下需要装箱(当用作泛型类型、超类型或可空类型时,简而言之,有点像原语)。但从技术上讲,它并不是真正用于Java方面的

    In java, I can call IdentifierFactory.Companion.buildString() and it will work, but IdentifierFactory.Companion.buildCountry() doesn't even exist.

    默认情况下,签名中包含值类的函数在Java中不可见,以避免Java中出现奇怪的重载问题。这是通过name mangling实现的。您可以通过使用Kotlin端工厂函数上的@JvmName注释覆盖Java方法的名称,使其在Java中可见:

    @JvmName("buildCountryUUID") // prevents mangling due to value class
    fun buildCountry(): CountryId {
        return CountryId.empty()
    }
    

    然后它可以在Java端访问,并返回一个UUID(内联值):

    UUID uuid = IdentifierFactory.Companion.buildCountryUUID();
    

    ideally, I'd just like the constructor to work and not use the factory

    我从评论中意识到,您是在从Java创建实际的CountryId实例之后。使用Java中的CountryId构造函数对我来说很好:

    CountryId country = new CountryId(UUID.randomUUID());
    

    但我不确定这怎么可能,因为生成的构造函数在字节码中是私有的