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

时间:2018-09-06 04:56:53

标签: enums kotlin

以下枚举定义有效。是否可以访问“内部属性” auditData或功能审核器?

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

GWGStatus.CHECKED.??? (does not work)

3 个答案:

答案 0 :(得分: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对象,因此似乎不是存储状态信息的正确位置。

答案 1 :(得分: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.declaredMethodsauditor()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反射看到它们(或者也许我没有使用正确的方法?;-)。所以:有些东西闻起来像是一个错误,但是我还不确定是什么错误:

  1. 不是应该首先创建一个子类吗?
  2. 子类是否应该在Kotlin本身中可以访问并可见?
  3. Kotlin编译器是否应该抱怨这一点,因为这还没有完成?
  4. 错误消息实际上是错误的,应该允许强制转换吗?
  5. 还有别的吗?

答案 2 :(得分:0)

您也可以只使用构造函数:

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

    fun auditor() = auditor
}

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