[英]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
如果current
是T
類型,則不能在current
上調用Node
class 的方法(例如setNext()
),因為在實例化LinkedList
時T
可以被任何 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;
是一個泛型類型,你在它上面調用setNext
和getNext
。 T
怎么知道它總是有這些方法? 這就是它不起作用的原因。
因此,您需要確保您的泛型類型 T 知道它具有setNext
和getNext
方法。
因此修復是:
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.