FindBugs - правило SE_BAD_FIELD, почему оно игнорирует java.lang.Object? - PullRequest
7 голосов
/ 05 мая 2011

Из описания SE_BAD_FIELD:

Непереходное непериализуемое поле экземпляра в сериализуемом классе

Этот класс Serializable определяет не примитивное поле экземпляра, которое не является ни временным, ни Serializable, ни java.lang.Object, и, по-видимому, не реализует интерфейс Externalizable или методы readObject () и writeObject (). Объекты этого класса не будут десериализованы правильно, если в этом поле хранится несериализуемый объект.

Почему java.lang.Object исключение из правила?

Ответы [ 2 ]

2 голосов
/ 06 мая 2011

Количество ложных срабатываний будет потенциально высоким, как

public void writeIt(Object o, ObjectOutputStream oos) {
    oos.writeObject(o);
}

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

Теперь вопрос в том, почему подпись вышеописанного метода отсутствует

public void writeIt(Serializable o, ObjectOutputStream oos) {
    oos.writeObject(o);
}

ответ заключается в том, что тогда все виды объектов, определенных интерфейсами, переданными в качестве первого параметра, не смогут скомпилироваться.

например

Map m = .....
writeIt(m, oos);

поэтому значение отлова сериализации java.lang.Object (что, вероятно, является чрезвычайно редким событием) не стоит ложного положительного воздействия.

1 голос
/ 05 мая 2011

Потому что все можно десериализовать обратно в java.lang.Object, поскольку каждый класс в java расширяет java.lang.Object.Если вам удастся сериализовать объект, который имеет несериализуемое поле, вы не сможете узнать класс этого поля при десериализации.Поскольку каждый класс является объектом, вы всегда можете использовать класс Object.

    class NonSerializableUser {}
    class SerializableUser implements Serializable{}

    class SomeObject implements Serializable{
        public NonSerializableUser nonUser;
        public SerializableUser user;
        public Object nonUserObj;

        public SomeObject(SerializableUser u, NonSerializableUser uu, NonSerializableUser uuu){
            user = u;
            nonUser = uu;
            nonUserObj = uuu;
       }
    }

В этом примере десериализация этого класса приведет к тому, что nonUser будет нулевым, пользователь будет правильным экземпляром класса SerializableUser, а nonUserObj будет не нулевым, однако он потеряет все методы и поля NonSerializableClass, они будутне были сериализованы.Единственными частями этого экземпляра, которые сериализуются, являются методы и поля, принадлежащие Object.

Стоит отметить, что многие библиотеки сериализации (например, ObjectOutputStream) будут жаловаться на не сериализуемый класс и не будутсериализуйте этот объект в первую очередь.Вот почему я пропустил детали этапа сериализации / десериализации.Однако многие xml-фреймворки по-прежнему сериализуют эти классы, и это, как правило, та ситуация, когда эта ошибка поднимает свою голову.

...