简体   繁体   English

与 Generics 不兼容的类型

[英]Incompatible Types with Generics

I am unfamiliar with generics, so in this method here where i'm trying to implement a remove method from scratch, :我不熟悉 generics,所以在这个方法中,我试图从头开始实现 remove 方法:

public class LinkedList<T> implements LinkedListInterface<T> {
    private Node head;
    private Node tail;
    private int count;
    public LinkedList () {
        head = null;
        tail = null;
        count = 0;
    }
    class Node {
        T data;
        Node next;
        
        Node(T data) {
            this.data = data;
            next = null;
        }
    }
    public Node getHead() {
        return head;
    }

    public T remove(int pos) throws ListException {
      if (pos < 1 || pos > count) {
        throw new ListException("Invalid position to remove from");
      }
      Node removedItem = null;
      if (count == 1) {
        removedItem = head;
        head = null;
        tail = null;
      }
      else if (pos == 1) {
        removedItem = head;
        head = head.next;
      }
      else if (pos == count) {
        removedItem = tail;
        Node prev = jump(pos - 2);
        prev.next = null;
        tail = prev;
      }
      else {
        Node prev = jump(pos - 2);
        removedItem = prev.next;
        prev.next = prev.next.next;
      }
      count--;
      return removedItem; // error: incompatible types: LinkedList<T>.Node cannot be converted to T
    }
}

I need help identifying what this 'T' is exactly in the remove method and what this error message means and what I should do to fix it, thanks for the help我需要帮助确定这个“T”在 remove 方法中到底是什么,这个错误信息是什么意思,我应该怎么做才能修复它,谢谢你的帮助

Generics (or rather, the proper name, 'type variables') is a way to link things . Generics(或者更确切地说,专有名称“类型变量”)是一种链接事物的方式。

All Ts represent a type.所有 T 代表一个类型。 Everyplace T is mentioned, it's the same type for any given 'usage' of a thing, but you don't know what T is.每个地方都提到了 T,它对于事物的任何给定“用法”都是相同的类型,但您不知道 T 是什么。 It could be Number, it could String, it could SomethingYouNeverHeardAbout.它可以是数字,可以是字符串,也可以是 SomethingYouNeverHeardAbout。 But it's some type or other.但它是某种类型或其他类型。 If you did know, you'd just write that out instead.如果你确实知道,你就会把它写出来。

In your snippet, public LinkedList<T> declares the type variable (just like you need to type int x; before you can start using x as a variable that can hold values , you need to declare a type variable , and that's where it is declared. T has no restrictions - it can be any type (except primitives, because primitive types and generics don't mix at all, at least, for now - maybe future java versions change this).在您的代码段中, public LinkedList<T>声明类型变量(就像您需要键入int x;在您开始使用x作为可以保存的变量之前,您需要声明一个类型变量,这就是它所在的位置declared.T 没有限制——它可以是任何类型(原始类型除外,因为原始类型和 generics 根本不混合,至少现在是这样——也许未来的 java 版本会改变这一点)。

All other occurrences of T in the entire file are simply usages of it.整个文件中出现的所有其他 T只是它的用法。

In other words, your code says: For any specific LinkedList, it has some type associated with it.换句话说,您的代码说:对于任何特定的 LinkedList,它都有一些与之关联的类型。 We have no idea what it is, but every instance has such a thing.我们不知道它是什么,但每个实例都有这样的东西。

Generics are entirely a compile time affair so this has no effect whatsoever when you run the code, it's solely for the compiler to help you out and tie things together. Generics 完全是编译时的事情,所以当你运行代码时这没有任何影响,它只是为了让编译器帮助你解决问题并将事情联系在一起。 The point of the exercise is simply to let you tell the compiler that various types used in different places are unknown, but we do know, they are the same.练习的目的只是让你告诉编译器,不同地方使用的各种类型是未知的,但我们知道,它们是相同的。

So, given any particular instance of LinkedList, its remove method returns the same type that its add method receives.因此,给定 LinkedList 的任何特定实例,其remove方法返回与其add方法接收的相同类型 Which is the same type as the data field of its internal Node inner class.与其内部Node内部class的data域是同一类型。

What does this get you?这对你有什么好处? Compile-time checking, for one.编译时检查,其中之一。 The compiler can now find bugs for you.编译器现在可以为您找到错误。 And so it has!所以它有! Your intent is clearly for the remove method to return the thing it removed, but you aren't doing that.您的意图显然是让remove方法返回它删除的东西,但您并没有这样做。 You are actually returning the node object that contains the thing you removed.您实际上正在返回包含您删除的内容的节点 object。 This node object isn't even publicly visible (your Node internal class has package private access), clearly completely useless to return that, and as per your signature, you didn't mean to.这个节点 object 甚至不是公开可见的(你的Node内部 class 有 package 私人访问),显然完全没有用返回它,并且根据你的签名,你不是故意的。

To fix your bug, just write return removedItem.data;要修复您的错误,只需编写return removedItem.data; instead.反而。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM