Как получить доступ к свойству и функциям Enum в Kotlin - PullRequest
0 голосов
/ 06 сентября 2018

Следующее определение перечисления является действительным. Можно ли получить доступ к «внутреннему свойству» AuditData или функции Auditor?

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

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

Ответы [ 3 ]

0 голосов
/ 06 сентября 2018

Вы также можете просто использовать конструктор:

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

    fun auditor() = auditor
}

Это все еще зависит от использования этого перечисления. Обратите внимание на предыдущий пост

0 голосов
/ 06 сентября 2018

Как только я увидел это, мне просто нужно было найти байт-код, так как я не мог представить, на что это должно быть переведено. Хотя я считаю, что «это» - ошибка, я покажу вам, что я обнаружил до сих пор.

Для 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, как и ожидалось, приведение не возможно в Котлине (пока?):

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

Теперь, используя утилиты отражения java в Kotlin (например, 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

Хорошо ... мы не можем видеть их, используя отражение Котлина (или, может быть, я не использовал правильный подход? ;-)). Итак: здесь что-то пахнет ошибкой, но я пока не уверен, что это за ошибка:

  1. разве не должен был быть создан подкласс?
  2. это подкласс должен быть доступен и видим в самом Kotlin?
  3. Неужели компилятор Kotlin должен был жаловаться на это, поскольку это еще не законченная функция?
  4. на самом деле сообщение об ошибке неверно, и оно должно было просто разрешить приведение?
  5. что-то еще?
0 голосов
/ 06 сентября 2018

Вы должны будете объявить переменные и функции в самом типе 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 объект, поэтому он не выглядит подходящим местом для хранения информации о состоянии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...