2016-01-04 3 views
4

Я искал веб-страницы, чтобы найти ответы на некоторые из запросов, связанных с классом enum в java.почему сериализация по умолчанию предотвращена в enum class

Мой запрос: почему default-сериализация была предотвращена в классе enum. Я могу видеть, что класс реализует Serializable перечисления интерфейса, но он также имеет 2 метод, как показано ниже -

private void readObject(ObjectInputStream in) throws IOException, 
    ClassNotFoundException { 
    throw new InvalidObjectException("can't deserialize enum"); 
} 

private void readObjectNoData() throws ObjectStreamException { 
    throw new InvalidObjectException("can't deserialize enum"); 
} 

я более смущен после просмотра этого класса. Любая помощь будет оценена. Заранее спасибо.

Я более смущен, так как ENUM реализует сериализуемый интерфейс и имеет вышеописанные методы, которые бросают «throw new InvalidObjectException (« не может десериализовать enum »); Исключение. так что я не получаю четкое представление о том, что выше двух методов?

Также комментарии к вышеуказанным двум методам говорят о предотвращении дезериализации по умолчанию, что это значит?

+0

Не дубликат, пожалуйста, проверьте изменения. – rraghuva

ответ

4

Значения перечисления являются сериализуемыми - и это все, что требуется при реализации интерфейса Serializable.

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 

public class Dummy { 

    public enum Color { 
     RED, GREEN, BLUE 
    } 

    public static void main(String[] args) throws Exception { 

     System.out.println(deserialize(serialize(Color.GREEN), Color.class)); 
    } 

    private static <T> T deserialize(byte[] data, Class<T> cls) throws IOException, ClassNotFoundException { 

     try (final ByteArrayInputStream stream = new ByteArrayInputStream(data); 
      final ObjectInputStream reader = new ObjectInputStream(stream)) { 

      return cls.cast(reader.readObject()); 
     } 
    } 

    private static byte[] serialize(Serializable obj) throws IOException { 

     final ByteArrayOutputStream stream = new ByteArrayOutputStream(); 

     try { 

      try (final ObjectOutputStream writer = new ObjectOutputStream(stream)) { 

       writer.writeObject(obj); 
      } 

     } finally { 

      stream.close(); 
     } 

     return stream.toByteArray(); 
    } 
} 

Однако, в связи с особым характером перечисления констант, время выполнения не можешь использовать механизм сериализации по умолчанию, так как это позволило бы строительству нескольких значений заданного постоянная, нарушая гарантии, что перечисление константы являются одноточечными.

По этой причине во время выполнения используется механизм «не по умолчанию» для сериализации/десериализации констант перечисления, который обеспечивает свойство singleton. Снятие с охраны механизма по умолчанию путем переопределения readObject - это просто мера безопасности, которая гарантирует, что вы не сможете обмануть виртуальную машину в создании новых констант за счет десериализации вредоносного взломанного потока байтов.

TL; DR Перечислительных константы прекрасно (де) сериализация, как утверждают, имеющие базовый класс Enum реализует интерфейс Serializable. Однако внутренне VM/run-time специально обрабатывает сериализацию и отключает механизм по умолчанию для этих объектов.

2

Простой, потому что в Java enum является одноэлементным в JVM, а deserialize() создаст другой экземпляр, таким образом, сломает однотонный контракт.

+0

Это означает, что мы можем сериализовать Enum, но не можем его десериализовать? – rraghuva

+0

Поскольку 'deserialize()' заблокирован, вы не можете использовать способ по умолчанию для переноса объектов enum', то есть сериализовать объекты enum, надеясь, что они могут быть десериализованы в другой JVM правильно. Обычный способ - использовать значение 'cardinal()'. –

Смежные вопросы