何时使用<>和<e>-Java泛型

时间:2018-12-26 08:45:11

标签: java generics

这是“ Java中的数据结构和算法(第六版)”一书中的代码片段 这是用于克隆SinglyLinkedList实现的示例方法。 为了更好地理解,我在Eclipse中进行了编码。

我有两个问题:

首先,在第3行中,我收到以下警告:键入安全性:“未经检查从对象到SinglyLinkedList<E>的转换”。为什么会这样?

第二,在第5行中,为什么我们有“ new Node<>( ...”,为什么不使用“ new Node<E>( ...” 两者有什么区别?

public SinglyLinkedList<E> clone( ) throws CloneNotSupportedException { 
    //always use inherited Object.clone() to create the initial copy
    SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone( ); //<---LINE 3 safecast

    if (size > 0) { // we need independent chain of nodes
        other.head = new Node<>(head.getElement( ), null);//<---LINE 5
        Node<E> walk = head.getNext( ); // walk through remainder of original list
        Node<E> otherTail = other.head; // remember most recently created node

        while (walk != null) { // make a new node storing same element
            Node<E> newest = new Node<>(walk.getElement( ), null);
            otherTail.setNext(newest); // link previous node to this one
            otherTail = newest;
            walk = walk.getNext( );
        } 
    } 
    return other;
}

3 个答案:

答案 0 :(得分:3)

  

首先,在第3行中,我收到以下警告:键入安全性:“未经检查从对象到SinglyLinkedList的转换”。为什么会这样?

方法clone()返回一个Object,因此您必须将其强制转换为SinglyLinkedList,编译器不能保证这样的Object将是SinglyLinkedList,所以你会得到警告。
我建议阅读有关Generics

的整个课程

如果要隐藏该警告,可以使用以下注释

@SuppressWarnings("unchecked")
public SinglyLinkedList<E> clone( ) throws CloneNotSupportedException { 
  

第二行,为什么我们有“ new Node <>(...”,为什么不使用“ new Node(...”)呢?两者之间有什么区别?

由于Java7,由于以下原因,在调用构造函数时无需声明泛型类型 Type Inference for Generic Instance Creation
如果您编写了= new Node(head.getElement( ), null);,那么您将创建一个原始类型而失去了泛型的优势。您也会得到警告。
JLS - Raw Type声明:

  

仅允许出于对遗留代码兼容性的考虑而使用原始类型。强烈反对在Java编程语言引入泛型之后编写的代码中原始类型的使用。 Java编程语言的未来版本可能会禁止使用原始类型。

答案 1 :(得分:1)

第3行:

您正在将super.clone()转换为SinglyLinkedList<E>的对象。该警告只是希望您检查super.clone()是否真的是SinglyLinkedList<E>的实例。您可以通过简单的选择来做到这一点:

if (super.clone() instanceof SinglyLinkedList<E>)
  SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone();

第5行:

那么您可以使用new Node <E>代替new Node<>。没有区别。简单地说,编译器已经知道您将实例化的泛型类型,因此使用new Node <E>完全是多余的。我不确定,但是我认为您必须在Java的早期版本(我认为Java 6及更低版本)中使用new Node <E>

答案 2 :(得分:1)

1)clone方法很需要返回Object see here,因此任何类型的转换都不安全

2)other.head已经是<E>,因此您不必<E>添加到新的变量中,编译器已经知道泛型的类型。