microcell (microcell) wrote,
microcell
microcell

Category:

Java: динамический тип enum

Enum в Java, это больше, чем просто набор констант. Поскольку каждая переменная в Java является объектом или стремится быть таковым, то, когда вы объявляете:

enum Numbers { ONE, TWO, THREE };

вы, на самом деле, создаёте четыре новых статических объекта. Объект Numbers и по одному объекту для каждой из констант. Это позволяет делать просто поразительные вещи, например, получить строку, содержащую имя константы:

String oneName = Numbers.ONE.name();

Или получить константу по её имени:

Numbers number = Numbers.valueOf("TWO");

Или сравнить две константы с проверкой на тип и инициализацию:

if (number.equals(Numbers.THREE);

Это довольно большое удобство, но оно действует ровно до того момента, пока вы точно знаете, какие именно константы вам потребуются. К несчастью, иногда вы не можете этого знать (к, примеру, если тип перечесления задаётся из некой базы данных). Как быть в таком случае?

К счастью, Java - это на столько гибкий язык, что он позволяет обманывать самого себя. Поскольку enum - это объект, как и все его члены, вам ничего не мешает сконструировать похожий объект, при условии, что он отвечает ряду требований. Этот объект, конечно, не будет вести себя так же, как полноценный член класса enum (ведь класс о нём ничего не будет знать). Вы не сможете, к примеру, использовать функцию valueOf для такой константы или использовать его для хеш-таблиц на подобии HashMap или HashSet, but everything comes with a price.

Итак, что надо сделать? Прежде всего, нам потребуется интерфейс:

interface Number {
    public String name();
}


Он необходим для того, что бы наш enum мог иметь что-то общее с динамическими константами.

Естественно, сам enum должен насследовать этот интерфейс:

enum Numbers implements Number { ONE, TWO, THREE };

Далее, создаём новый класс, который будет создавать динамические константы:

final class DynamicNumber implements Number {
    private final String number;

    // прячем конструктор, просто для красоты
    private DynamicNumber(final String name) {
        number = name;
    }

    public boolean equals(Object other) {
        if (other instanceof Number)
            return number.equals(((Number) other).name();
        return false;
    }

    public int hashCode() {
        return number.hashCode();
    }

    public String name() {
        return number;
    }

    public String toString() {
        return number;
    }

    public static DynamicNumber withName(String name) {
        return new DynamicNumber(name);
    }
}

DynamicNumber FOUR = new DynamicNumber("FOUR");

if (FOUR.equals(Numbers.THREE)); // false
Tags: java, пособие по вкручиванию лампочек
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 0 comments