如何在Kotlin中访问Enum属性和函数

问题描述 投票:3回答:3

以下枚举定义有效。是否可以访问“内部属性”auditData或函数审计员?

enum class GWGStatus {
    UNCHECKED,
    CHECKED {
        lateinit var auditDate: Date
        fun auditor() : String = "Peter"
    }
}

GWGStatus.CHECKED.??? (does not work)
enums kotlin
3个回答
2
投票

您必须在enum类型中声明变量和函数,然后在enum实例中覆盖它们。

不幸的是,由于并非你所有的enum实例都实现了这个功能,你不能使它成为abstract并且必须提供默认实现:

import java.util.*

enum class GWGStatus {
    UNCHECKED,
    CHECKED {
        override lateinit var auditDate: Date
        override fun auditor(): String = "Peter"
    };

    open lateinit var auditDate: Date
    open fun auditor(): String = ""
}

fun main(vararg args: String) {
    GWGStatus.CHECKED.auditDate = Date()

    println(GWGStatus.CHECKED.auditDate)
    println(GWGStatus.CHECKED.auditor())
}

但请注意,这个enum用法感觉很奇怪。您将状态数据存储在旨在成为常量对象的内容中。内存中只会有一个GWGStatus.CHECKED对象,因此它似乎不是存储状态信息的正确位置。


2
投票

一看到这个,我就只需要查找字节码,因为我无法想象应该将其转换为什么。虽然我相信“它”是一个错误,但我会告诉你到目前为止我发现了什么。

对于CHECKED,实际上创建了自己的子类,即public final class GWGStatus$CHECKED extends GWGStatus,尽管GWGStatus本身就是一个枚举。可能是JVM字节码中允许的内容,但在Java语言规范中是不允许的。

现在来的是不那么一致的部分。虽然以下适用于Java:

GWGStatus.CHECKED status = (GWGStatus.CHECKED) GWGStatus.CHECKED;
status.auditDate = new Date();
System.out.println(status.auditor());

按照预期打印Peter,在Kotlin中无法进行演员表演(但是?):

GWGStatus.CHECKED as GWGStatus.CHECKED // fails: Use of enum entry names as types is not allowed, use enum type instead

现在在Kotlin中使用java反射实用程序(例如status::class.java.declaredFields.java.declaredMethods),auditor()getAuditDate()(等)都是可见的和可访问的(正如Java代码本身已经证明的那样)。进一步分析并仅使用Kotlin反射:

GWGStatus.UNCHECKED::class // returns class GWGStatus
GWGStatus.CHECKED::class // return class GWGStatus$CHECKED ... that's good so far
GWGStatus.CHECKED::class.declaredMembers // empty list ... didn't expect this one
// empty too: GWGStatus.CHECKED::class.declaredMemberProperties
// and GWGStatus.CHECKED::class.declaredFunctions
GWGStatus.CHECKED::class.superTypes // shows GWGStatus as expected
GWGStatus.CHECKED::class.members // shows clone(), finalize(), name, equals, hashcode, tostring, getdeclaringclass, ordinal... nothing we are interested in and rather the ~general enum members
GWGStatus::class.nestedClasses // empty too

好的......我们无法使用Kotlin反射看到它们(或者我没有使用正确的方法?;-))。所以:这里的东西闻起来像臭虫,但我不确定这个bug是什么:

  1. 是不是应该首先创建一个子类?
  2. 是什么子类应该在Kotlin本身可访问和可见?
  3. 是不是Kotlin编译器应该抱怨这个,因为这不是一个完成的功能呢?
  4. 事实上错误信息是错误的,它应该只允许演员?
  5. 别的什么?

0
投票

您也可以使用构造函数:

enum class GWSGStatus(var date: Date, private var auditor: String) {
    UNCHECKED(Date(), ""),
    CHECKED(Date(), "Peter");

    fun auditor() = auditor
}

它仍然取决于这个枚举的用法。注意以前的帖子

© www.soinside.com 2019 - 2024. All rights reserved.