статика внутри внутренних классов: serialVersionUID - PullRequest
2 голосов
/ 04 февраля 2011

Я пытаюсь развить свои личные библиотечные классы, но наталкиваюсь на контрольно-пропускной пункт. Мой класс утилит состоит из статических методов и констант, а также нескольких открытых внутренних классов для различных структур данных и вспомогательных утилит. Эти классы НЕ являются статическими вложенными классами, они предназначены для создания экземпляров, хранения данных и т. Д.

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

Есть ли способ обойти это? Должен ли родительский класс содержать UID (даже если он фактически статический). В данный момент я начинаю задумываться о том, чтобы превратить мой класс Utilities в набор классов, и отказываюсь от идеи единого класса утилит импорта. Однако он превращается во все более и более широкий набор утилит.

К.Барад JDK1.6 u23

edit: быстрый пример кода.

public class UtilDummy {
    public static final Date version = new Date(111,01,04);

    public static final int SUCCESS = 0;
    public static final int READ_FAIL = -1;


    public class TupleComp<E1 extends Serializable, E2 extends Serializable, E3 extends Serializable>
        implements Cloneable, Serializable {
    /** version : Date object for the version of this class */
    public final Date version = new Date(111, 01, 04);
    public E1    elem1   = null;
    public E2    elem2   = null;
    public E3    elem3   = null;

    public TupleComp() {
    }

    public TupleComp(E1 elem1, E2 elem2, E3 elem3) {
        this.elem1 = elem1;
        this.elem2 = elem2;
        this.elem3 = elem3;
    }

    @Override
    public TupleComp<E1, E2, E3> clone() {
        return new TupleComp<E1, E2, E3>(elem1, elem2, elem3);
    }

    public boolean equals(TupleComp<E1, E2, E3> target) {
        boolean out = true;
        out &= (elem1 == null ? target.elem1 == null : elem1.equals(target.elem1));
        out &= (elem2 == null ? target.elem2 == null : elem1.equals(target.elem2));
        out &= (elem3 == null ? target.elem3 == null : elem1.equals(target.elem3));
        return out;
    }

    }
}

внутренний класс выдает предупреждения, и довольно релевантный, но так как он не может принимать статические поля, я не могу добавить public static final long serialVersionUID

редактировать : Итак, такая строка, как public static final long ll = 1; Это хорошо. Дело в том, что я действительно хочу сделать: публичная статическая окончательная Дата версии = новая Дата (111, 01, 04); public static final long serialVersionUID = version.getTime ();

Это работает в классе верхнего уровня, но во внутренних классах возникает: «Версия поля не может быть объявлена ​​статической; статические поля могут быть объявлены только в статических типах или типах верхнего уровня»

Даты являются для меня наиболее практичным способом хранения значимой и инкрементальной системы отслеживания версий, которая сопоставима и может быть разбита на основные и второстепенные части. Кто-нибудь знает, что с объектом Date вызывает проблему;

Закрыто

Кажется, с моей стороны было какое-то недопонимание о том, как ведет себя статический класс, и что это решение проблемы. Я, вероятно, (в конце концов) разделю классы, но пока это самое разумное решение. Спасибо всем, кто ответил

Ответы [ 4 ]

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

Этот

class MyClass {
    class Inner {
        static final int x = 1;
    }
}

отлично смотрится в моей IDE (IntelliJ 9).Однако без final он действительно жалуется.

Так как UUID должен быть постоянным, я думаю, final должно быть в порядке для вас (и даже даже рекомендуется).

Обновление

Копирование вашего примера внутреннего класса в мою IDE и добавление в него static final int также вполне нормально, никаких жалоб со стороны компилятора.

Update2

Однакодобавление квалификатора final к объекту Date действительно приводит к ошибке!Вы подтверждены: -)

Но когда я пробую это с String, нет проблем.Может ли это быть из-за того, что примитивы и String неизменны, а Date - нет?

Update3

Нет.BigDecimal также не работает.Я вне теории: - (

Update4

Google - мой друг :-) Оказывается вам нужно объявить свой внутренний класс static, тогда все нормально и шикарно: все вышеупомянутые статические поля компилируются.Из отрывка кода, который вы показываете, кажется, что нет никакого повода для того, чтобы ваш внутренний класс был нестатическим, поэтому я думаю, что это решение должно подойти вам.

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

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

Не беспокойтесь о большом импорте, Eclipse автоматически обрабатывает их.Также, если у вас большой объем импорта, это указывает на то, что класс несет большую ответственность и, возможно, его следует разделить.Я предполагаю, что обычно другие классы будут использовать только несколько ваших служебных классов.

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

В вашем примере это не должно быть проблемой, чтобы сделать TupleComp статическим - он не зависит (не нуждается) в экземпляре внешнего экземпляра. Статический класс означает, что его экземпляры не являются членами внешнего класса. То есть вложенные экземпляры неявным образом не получают указатель на внешний. Каждый экземпляр вложенного (статического) экземпляра по-прежнему будет иметь свои собственные данные (разные для каждого экземпляра).
Попробуйте это:

public class UtilDummy {

    public static final Date version = new Date(111,01,04);

    public static final int SUCCESS = 0;
    public static final int READ_FAIL = -1;


    public static class TupleComp<E1 extends Serializable, E2 extends Serializable, E3 extends Serializable>
    implements Cloneable, Serializable {
        private static final long serialVersionUID = 1L;
        /** version : Date object for the version of this class */
        public final static Date version = new Date(111, 01, 04);
        public E1    elem1   = null;
        public E2    elem2   = null;
        public E3    elem3   = null;

        public TupleComp() {
        }

        public TupleComp(E1 elem1, E2 elem2, E3 elem3) {
            this.elem1 = elem1;
            this.elem2 = elem2;
            this.elem3 = elem3;
        }

        @Override
        public TupleComp<E1, E2, E3> clone() {
            return new TupleComp<E1, E2, E3>(elem1, elem2, elem3);
        }

        public boolean equals(TupleComp<E1, E2, E3> target) {
            boolean out = true;
            out &= (elem1 == null ? target.elem1 == null : elem1.equals(target.elem1));
            out &= (elem2 == null ? target.elem2 == null : elem2.equals(target.elem2));
            out &= (elem3 == null ? target.elem3 == null : elem3.equals(target.elem3));
            return out;
        }
    }
}

Тест:

public class Test {

    public static void main(String[] args) {
        UtilDummy.TupleComp<String, String, String> t1 = new UtilDummy.TupleComp<String, String, String>("a", "b", "c");
        UtilDummy.TupleComp<String, String, String> t2 = new UtilDummy.TupleComp<String, String, String>("a", "b", "c");
        UtilDummy.TupleComp<String, String, String> t3 = new UtilDummy.TupleComp<String, String, String>("1", "2", "3");
        System.out.println(t1.equals(t2));  // true
        System.out.println(t1.equals(t3));  // false !
    }
}  

Кстати: метод equals был неправильным: сравнивал elem2 и elem3 с elem1!

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

вы не можете иметь статическую переменную во внутреннем классе

Это совершенно неправильно! вы можете. Но только 'final' - вот какой должен быть serialVersionUID.

package my;

import java.io.Serializable;

class InnerSVUIDTest {
    class A implements Serializable{
        private static final long serialVersionUID = -8981530002081262605L;
    }

    Serializable bshit = new Serializable (){
        private static final long serialVersionUID = -1655811639867903884L;

    };
}
...