приведение байта к перечислению - PullRequest
2 голосов
/ 04 апреля 2011

У меня есть следующий код:


public enum PortableTypes { Boolean, etc...};

public void testConversion() {
  byte b = 5;
  PortableTypes type = (PortableTypes)b;
}

Когда я компилирую, мне говорят, что это необратимые типы. Я не знал, что что-то такое простое, как это, будет оставлено вне Java. Я что-то упустил или Java просто не поддерживает приведение в enum вообще? Я также проверил с int, и это не удалось.

Если это не поддерживается, какой самый простой обходной путь?

EDIT:

Поскольку все продолжают жаловаться на «плохой дизайн», я объясню немного дальше. Я использую enum для представления типов, которые вы можете отправить с помощью моего TcpServer. Пакет отправляется с этим типом, и на принимающей стороне я смотрю на тип и использую его для преобразования байтов, считываемых из пакета, в пригодные для использования данные. Очевидно, что вы не можете отправить перечисление с помощью OutputStream, поэтому мне нужно преобразовать значение перечисления в числовое значение для отправки. Я не согласен с идеей, что это «плохой дизайн», я думаю, что Enums действительно должен использоваться именно для этой цели, но этот дизайн не работает в Java, потому что он строго типизирован.

Ответы [ 8 ]

6 голосов
/ 04 апреля 2011

Вы, вероятно, думаете о enum как о чем-то похожем на то, что мы имеем в c / C ++ или C #, что по сути является синтаксическим сахаром для объявления констант.

Java enum - это совершенно другой зверь, хотя ... Это встроенная реализация шаблона Typesafe Enum . Поскольку он строго типизирован, невозможно непосредственно привести перечисление из байта или даже целого числа.

Но все перечисления являются полными классами в Java, поэтому ничто не мешает вам реализовать дополнительный метод, который выполняет это преобразование для вас.

Надеюсь, это поможет.

Редактировать: Опять же, я не программист на Java, но думаю, что-то вроде этого будет работать:

public enum PortableTypes {
    Boolean,
    Type2,
    Type3;

    public static PortableTypes convert(byte value) {
        return PortableTypes.values()[value];
    }        
};

public void testConversion() {
    byte b = 5;
    PortableTypes type = PortableTypes.convert(b);
}

Дайте мне знать, если это работает.

3 голосов
/ 04 апреля 2011

У перечислений Java есть порядковые номера, чтобы помочь вам.

Чтобы перейти от константы к номеру, позвоните WHATEVER.ordinal().Возвращает индекс константы в порядке объявления.Итак, для:

enum Underwear { BRIEFS, BOXERS };

Underwear.BRIEFS.ordinal() равно 0, а Underwear.BOXERS.ordinal() равно 1.

Чтобы перейти от числа к объекту перечисления, вызовите values() и индексируйте возвращаемое значениемассив.

Рот лошади здесь: http://download.oracle.com/javase/6/docs/api/java/lang/Enum.html

2 голосов
/ 04 апреля 2011

Самое эффективное решение - передавать сообщения туда и обратно с ObjectOutputStream. Это хорошо по ряду причин.

  1. Встроенная enum сериализация
  2. Возможность более сложной передачи сообщений более плавная
  3. Способность передавать обратные вызовы и параметры также включена!
2 голосов
/ 04 апреля 2011

Перечисление обозначается как тип (хотя по умолчанию оно имеет значение int, обычно в постоянстве и т. Д.), Оно фактически имеет тип. Больший вопрос в том, почему вы хотите разыграть его, как я бы подал в разделе «Плохая практика». Строгая типизация - главное преимущество современных языков.

Если вам просто нужно прочитать значение байта в шаблонах enum design в Java.

Если вам нужно значение, вы можете сделать что-то вроде:

enum SomeEnum
{
    a((byte)0x01),
    b((byte)0x02),
    c((byte)0x03),
    d((byte)0x04);

    byte byteVal;

    SomeEnum(byte b)
    {
      byteVal = b;
    }

    //Continued long winded example
    public MyNum replacementValueOf(byte b)
    {
      for(MyNum num : MyNum.values())
        if(b == num.getByte())
          return num;
      throw new RuntimeException("Your byte " + b + " was not a backing value for MyNum.");
    }
}

Я давал подробный ответ, но я согласен с постами выше, переосмыслим шаблон дизайна.

2 голосов
/ 04 апреля 2011

Или напишите статический метод получения:

PortableTypes.get(b);

public static PortableTypes get(byte b) {
  return PortableTypes.values()[b];
}
1 голос
/ 04 апреля 2011

Вы можете попробовать создать метод для вашего перечисления, который принимает байт.Это может выглядеть примерно так:

public enum PortableTypes { 
    Boolean, //etc....
    Int;


    public statc PortableTypes fromByte(byte b) {

        for(PortableTypes t : values())
        {
            if(t.ordinal() == (int)b)
                return t;
        } 
        return null;  //or throw exception
    }
}

У меня сейчас нет удобной IDE, но я верю, что что-то подобное сработаетНадеюсь, это поможет.

1 голос
/ 04 апреля 2011

Я не уверен, что это хорошая идея. Вы могли бы сделать PortableTypes.values()[b], но было бы лучше переосмыслить дизайн.

0 голосов
/ 04 апреля 2011

Вы можете приводить только от супертипа к производному типу, если тип на самом деле является производным типом.Перечисления не являются разновидностями байтов или наоборот.

...