Java Generics, связанный список

Я закончил изучать дженерики, и мне было нелегко. Тем не менее, я это понял. Вот что я понял. Я хочу, чтобы вы поправили меня, где я ошибаюсь, и ответили на несколько вопросов :) .

public class LinkedList<T> {
//class definition
}

  • Это означает, что LinkedList‹> — это класс, который будет принимать объекты классов, а также интерфейсы.
  • public class LinkedList<T extends Object> {
    //class definition
    }
    

  • Это означает, что LinkedList‹> — это класс, который будет принимать объекты тех классов, которые только расширяют класс Object. В общем, все классы. В случае необработанного типа T будет заменен на Object
  • public class LinkedList<T extends Object & java.lang.Serializable> {
    //class definition
    }  
    

  • Это означает, что LinkedList‹> — это класс, который принимает объекты всех тех классов, которые реализуют интерфейс Serializable. Если объект пользовательского класса должен быть включен в список, то пользовательский класс должен реализовывать Serializable.
  • public class LinkedList<T> implements Iterable<T> {
    //class definition
    }  
    

  • Это означает, что класс LinkedList‹> можно использовать с циклом for на основе коллекции. Он должен перегружать метод iterator() и иметь внутренний класс, который реализует Itarator<T> и перегружает hasNext(), next() и remove().

  • Questions
    1. Please explain the meaning of this in simple words and with an example, if possible:
    public class BinaryTree<T extends Comparable<? super T>> what replaces the ? 2. I want to write the above mentioned LinkedList<> class to a file using the writeObject() method. so I declare it as

    public class LinkedList<T extends Object> implements Serializable {
         //methods and data members      
    private class Node implements Serializable { //inner class
                      T object;
                      Node next;
               }
        }
    

    Должен ли внутренний класс также реализовывать Serializable?


    person A User    schedule 01.06.2012    source источник


    Ответы (3)


    О ваших четырех первых пунктах:

    1. Список, который должен содержать экземпляры T (включая классы, расширяющие T).
    2. Фактически идентичен первому, так как все классы расширяют Object.
    3. Список, который может содержать только объекты Serializable (то же, что class LinkedList<T extends Serializable> { ... })
    4. Итерируемый список T, так что да, его можно использовать в расширенных циклах.

    Стоит отметить, что когда мы говорим «список, который может содержать только объекты указанного типа», мы должны говорить «должен» вместо «может». Если вы не передадите Class<?> объектов, Java (среда выполнения) не будет проверять переданные значения на самом деле, это будет делать только компилятор и только на основе видимого статического типа, который мог быть изменен вручную (это выдаст предупреждение) .

    О вопросах:

    1. Он представляет собой BinaryTree, содержащий объекты, которые Comparable относятся к любому объекту того же класса, что и T, или любому из его супертипов (Object — это один супертип всех классов, по сути, всех классов, которые T расширяет, и всех интерфейсов, которые он реализует).
    2. Если вы хотите сериализовать объект, используя writeObject, то все непереходные (т. е. те, которые вы не можете перестроить на основе других данных) поля экземпляра этого объекта также должны быть Serializable или writeObject будет их игнорировать. Выдержки из вашего кода недостаточно, чтобы сказать, должно ли Node быть Serializable или нет, но, вероятно, оно должно дать общую идею примера List.
    person Romain    schedule 01.06.2012
    comment
    @FasihKhatib Указание на то, имеет ли LinkedList нестатическое поле типа Node. - person Romain; 01.06.2012
    comment
    Я планировал добавить нестатический метод public void writeIt(), который создавал бы ObjectOutputStream, а затем использовал бы writeObject(this) - person A User; 01.06.2012
    comment
    Да, у него будет нестатический Node start, указывающий на начало списка, Node end, указывающий на конец списка. Node current, чтобы указать на текущий узел. - person A User; 01.06.2012
    comment
    Три: start, end и current необходимы для обхода списка. - person A User; 01.06.2012
    comment
    Итак, Node должен быть Serializable. - person Romain; 04.06.2012

    Чтобы добавить некоторые уточнения:

    T обозначает любой ссылочный тип; это может быть класс, интерфейс, массив или параметризованный тип. Нет различий между классами и интерфейсами и т.д.

    T extends Object совпадает с T, потому что каждый ссылочный тип является подтипом Object (да, интерфейсы также являются подтипами Object). extends Object как бы избыточно.

    T extends Object & Serializable требует, чтобы T был подтипом как Object, так и Serializable. Так как, как мы уже сказали, все является подтипом Object, то пока вы можете считать его таким же, как T extends Serializable (немного отличается, потому что в первом случае стирание T будет Object, а во втором случае Serializable; но вы не нужно беспокоиться об этом на данный момент).

    person newacct    schedule 01.06.2012

    Из рекомендаций Oracle:

    Примечание. Сериализация внутренних классов (т. е. вложенных классов, не являющихся статическими классами-членами), включая локальные и анонимные классы, настоятельно не рекомендуется по нескольким причинам. Поскольку внутренние классы, объявленные в нестатических контекстах, содержат неявные непереходные ссылки на вмещающие экземпляры классов, сериализация такого экземпляра внутреннего класса также приведет к сериализации связанного с ним экземпляра внешнего класса. Синтетические поля, сгенерированные javac (или другими компиляторами JavaTM) для реализации внутренних классов, зависят от реализации и могут различаться между компиляторами; различия в таких полях могут нарушить совместимость, а также привести к конфликту значений serialVersionUID по умолчанию. Имена, присвоенные локальным и анонимным внутренним классам, также зависят от реализации и могут отличаться в разных компиляторах. Поскольку внутренние классы не могут объявлять статические члены, отличные от постоянных полей времени компиляции, они не могут использовать механизм serialPersistentFields для обозначения сериализуемых полей. Наконец, поскольку внутренние классы, связанные с внешними экземплярами, не имеют конструкторов с нулевым аргументом (конструкторы таких внутренних классов неявно принимают охватывающий экземпляр в качестве предшествующего параметра), они не могут реализовать Externalizable. Однако ни одна из перечисленных выше проблем не относится к статическим классам-членам.

    Сериализируемый интерфейс, Определение сериализуемых полей для класса

    person Alex Stybaev    schedule 01.06.2012