【问题标题】:Java Generics, Linked ListJava 泛型,链表
【发布时间】:2012-06-06 19:52:52
【问题描述】:

我学完了泛型,但并不容易。不过,我确实明白了。这是我的理解。我希望您纠正我的错误并回答几个问题:)。

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&lt;T&gt; 并重载 hasNext()、next() 和 remove() 的内部类

  • 问题
    1. 请尽可能用简单的语言和例子解释这个的意思:
    公共类BinaryTree&lt;T extends Comparable&lt;? super T&gt;&gt; 什么取代了? 2. 我想使用 writeObject() 方法将上面提到的 LinkedList 类写入文件。所以我将其声明为
    public class LinkedList<T extends Object> implements Serializable {
         //methods and data members      
    private class Node implements Serializable { //inner class
                      T object;
                      Node next;
               }
        }
    

    内部类是否也必须实现 Serializable ?

    【问题讨论】:

      标签: java generics serialization singly-linked-list


      【解决方案1】:

      关于你的前四点:

      1. 应该包含T 实例的列表(包括扩展T 的类)。
      2. 实际上与第一个相同,因为所有类都扩展 Object
      3. 只能包含Serializable 对象的列表(与class LinkedList&lt;T extends Serializable&gt; { ... } 相同)
      4. T 的可迭代列表,是的,它可以用于增强循环。

      值得注意的是,当我们说“只能包含指定类型的对象的列表”时,我们应该说“应该”而不是“可以”。除非您传递Class&lt;?&gt; 对象,否则Java(运行时)不会检查传入的值实际上是否符合,只有编译器会,并且仅基于可见的静态类型,这可能已经手动更改(这会发出警告)。

      关于问题:

      1. 它表示一个BinaryTree,其中包含与T 或其任何超类型相同类的任何对象的Comparable 对象(Object 是所有类的一个超类型,基本上是@987654333 的所有类@extends 及其实现的所有接口)。
      2. 如果您想使用writeObject 序列化对象,则该对象的所有非瞬态(即您不能基于其他数据重建)实例字段也需要为Serializable,或writeObject will ignore them。您的代码提取不足以判断 Node 是否需要为 Serializable,但它可能需要给出 List 示例的一般概念。

      【讨论】:

      • @FasihKhatib 指示LinkedList 是否具有Node 类型的非静态字段。
      • 我正计划添加一个非静态方法public void writeIt(),它会创建一个ObjectOutputStream,然后使用writeObject(this)
      • 是的,它将有非静态 Node start 指向列表的开头,Node end 指向列表的结尾。 Node current 指向当前节点。
      • 列表遍历需要start、end和current这三个。
      • 那么,Node 需要可序列化。
      【解决方案2】:

      添加一些说明:

      T 代表任何引用类型;它可以是类、接口或数组,也可以是参数化类型。类和接口等没有区别。

      T extends ObjectT 相同,因为每个引用类型都是Object 的子类型(是的,接口也是Object 的子类型)。 extends Object 有点多余。

      T extends Object &amp; Serializable 要求 TObjectSerializable 的子类型。因为正如我们之前所说,一切都是Object 的子类型,现在您可以认为它与T extends Serializable 相同(略有不同,因为在第一种情况下,T 的擦除将是Object 和在第二种情况下Serializable;但此时您无需担心这一点)。

      【讨论】:

        【解决方案3】:

        来自 Oracle 指南:

        注意 - 强烈建议不要序列化内部类(即不是静态成员类的嵌套类),包括本地和匿名类,原因有几个。因为在非静态上下文中声明的内部类包含对封闭类实例的隐式非瞬态引用,所以序列化这样的内部类实例也会导致其关联的外部类实例的序列化。由 javac(或其他 JavaTM 编译器)生成的用于实现内部类的合成字段是依赖于实现的,并且可能因编译器而异;此类字段的差异可能会破坏兼容性并导致默认 serialVersionUID 值冲突。分配给本地和匿名内部类的名称也取决于实现,并且可能因编译器而异。由于内部类不能声明编译时常量字段以外的静态成员,因此它们不能使用 serialPersistentFields 机制来指定可序列化字段。最后,因为与外部实例关联的内部类没有零参数构造函数(此类内部类的构造函数隐式接受封闭实例作为前置参数),它们无法实现 Externalizable。然而,上面列出的所有问题都不适用于静态成员类。

        Serializible Interface, Defining Serializable Fields for a Class

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-03
          • 1970-01-01
          • 1970-01-01
          • 2021-01-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多