Создание перечисления Java в Scala
мое рабочее место экспериментировало в переходе от Java к Scala для некоторых задач, и это хорошо работает для того, что мы делаем. Однако некоторые существующие методы ведения журнала ожидают java.lang.Enum
. Метод ведения журнала определен в базовом классе (Java), и подклассы могут определять свои собственные перечисления, которые регистратор будет отслеживать во всех экземплярах в нескольких потоках/машинах.
это работает так в Java:
public class JavaSubClass extends JavaBaseClass {
enum Counters {
BAD_THING,
GOOD_THING
}
public void someDistributedTask() {
// some work here
if(terribleThing) {
loggingMethod(Counters.BAD_THING)
} else {
loggingMethod(Counters.GOOD_THING)
// more work here
}
}
}
затем, когда задача будет завершена, мы сможем увидеть это
BAD_THING: 230
GOOD_THING: 10345
есть ли способ воспроизвести это в Scala, либо создав Java Enum
s или преобразование из Enumeration
to Enum
? Я попытался расширить Enum
напрямую, но он, кажется, запечатан, так как я получаю ошибку в консоли:
error: constructor Enum in class Enum cannot be accessed in object $iw
Access to protected constructor Enum not permitted because
enclosing object $iw is not a subclass of
class Enum in package lang where target is defined
3 ответов
Если вам нужно перечисление java, то вам нужно написать его на Java. Есть вещи, которые вы можете сделать в Scala, чтобы заменить варианты использования of Enum
, но в Scala нет ничего, что повторяет механику Java Enum
.
Перечисления Java
для класса enum Counter
было бы лучше, чем Counters
- каждого значения enum представляет особой борьбы.
когда javac компилирует enum
класс, это:
- компилируется в обычный класс java (например.
Counter
), содержащий все конструкторы, методы, другие члены перечисления (если есть) -
каждого
enum
значение (GOOD_THING
,BAD_THING
) является
хотя это, вероятно, не очень хорошая идея (см. другие сообщения для реальных хороших идей), это is можно продлить java.lang.Enum
в Scala. Ваш код работал бы, если бы вы поместили класс и его сопутствующий объект в одну и ту же единицу компиляции (в REPL каждый оператор выполняется в своей собственной единице компиляции, если вы не используете :paste
режим).
если вы используете :paste
mode и вставить в следующий код, Scala с удовольствием скомпилирует это:
sealed class AnEnum protected(name: String, ordinal: Int) extends java.lang.Enum[AnEnum](name, ordinal)
object AnEnum {
val ENUM1 = new AnEnum("ENUM1",0)
case object ENUM2 extends AnEnum("ENUM2", 1) // both vals and objects are possible
}
однако взаимодействие Java, вероятно, не будет удовлетворительным. Компилятор Java добавляет static values
и valueOf
методы новые enum
классы и гарантирует, что имена и ординалы верны, чего Scala не будет.
даже если вы сами выполните эти шаги, Java не будет доверять вашему перечислению, потому что у класса нет ENUM
модификатор. Это значит, что Class::isEnum
скажет, что ваш класс не является перечислением, которое повлияет на static Enum::valueOf
способ, например. Оператор switch Java также не будет работать с ними (хотя сопоставление шаблонов Scala должно работать, если значения перечисления являются объектами case).