簡體   English   中英

Java 中的泛型在定義方法時拋出錯誤

[英]Generic in Java throwing errors when methods are defined

我在 Java 中學習 Generics。 為此,我嘗試了一個類似的簡單 LinkedList。

class Node {
  private int age;
  private String name;
  private Node next;

  public Node(int age, String name) {
    this.age = age;
    this.name = name;
    this.next = null;
  }

  public int getAge() {
    return this.age;
  }

  public String getName() {
    return this.name;
  }

  public Node getNext() {
    return this.next;
  }

  public void setNext(Node next) {
    this.next = next;
  }
}

class LinkedList<T> {
  private T head;
  private T current;

  public LinkedList() {
    head = null;
    current = null;
  }

  public void append(T x) {
    if (head == null) {
      head = x;
      current = x;
    }
    else {
      current.setNext(x);
      current = x;
    }
  }

  public T getAt(int index) {
    T ptr = head;
    for(int i = 0; i < index; i++) {
      ptr = ptr.getNext();
    }
    return ptr;
  }
}

class Main {
  public static void main(String[] args) {
    LinkedList<Node> list = new LinkedList<Node>();
    list.append(new Node(39, "John"));
    list.append(new Node(43, "Josh"));
    Node x = list.getAt(1);
    System.out.println(String.format("%d, %s", x.getAge(), x.getName()));
  }
}

但是我收到了這個錯誤,而節點 class 中確實存在所有方法。 我在做什么錯?

LinkedList.java:16: error: cannot find symbol
      current.setNext(x);
             ^
  symbol:   method setNext(T)
  location: variable current of type T
  where T is a type-variable:
    T extends Object declared in class LinkedList
LinkedList.java:24: error: cannot find symbol
      ptr = ptr.getNext();
               ^
  symbol:   method getNext()
  location: variable ptr of type T
  where T is a type-variable:
    T extends Object declared in class LinkedList
2 errors

如果currentT類型,則不能在current上調用Node class 的方法(例如setNext() ),因為在實例化LinkedListT可以被任何 class 替換。

您的Node class 不應該是LinkedList的泛型類型參數。 LinkedList應始終由Node組成。 每個Node中存儲的數據類型應該是泛型類型。

class Node<T> {
  private T data;
  private Node next;

  public Node(T data) {
    this.data = data;
    this.next = null;
  }
}

並且LinkedList應該包含Node<T>節點:

class LinkedList<T> {
  private Node<T> head;
  private Node<T> current;
}

編譯器無法理解 T 類型。 您已經使用t.setNext() ,但是除非實際使用它,否則它不會出現在 T 定義中。 我在這里可能聽起來有點混亂,但試試這個:

創建一個具有 setNext 和 getNext 方法的接口Contract 實現 Node 擴展上面的接口。 Node implements Contract 在鏈接列表中將 generics 更改為T extends Contract

任何給定的泛型T都沒有hasNext ,因此代碼無法編譯

您必須確保 LinkedList 僅包含 Node 類或其子類型

class LinkedList<T extends Node>

但請注意:T 與存儲在節點中的泛型不同,所以這看起來更好

class LinkedList<T> {
    Node<T> head;

private T current; 是一個泛型類型,你在它上面調用setNextgetNext T怎么知道它總是有這些方法? 這就是它不起作用的原因。

因此,您需要確保您的泛型類型 T 知道它具有setNextgetNext方法。

因此修復是:

T extends NodeAbstract了 NodeAbstract,其中 NodeAbstract 是聲明這些方法簽名的接口。 現在這確保了任何 T 得到的東西總是有這兩種方法。

您必須制作Node<T>LinkedList<Node>

public void append(T x) { // Here x is of Type T
if (head == null) {
  head = x;
  current = x; //Assigning x to current, current is also of Type T
}
else {
  current.setNext(x); // T.setNext is not defined! Because T can be a String/Integer/whatever. They do not have setNext method
  current = x;
}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM