为什么当参数和参数匹配时会发生 javac 错误“(x) 无法应用于 (y)”? (内部-class 调用外部-class 方法)
Why does the javac error "(x) cannot be applied to (y)", happen when both parameters and arguments match up? (inner-class calling outer-class method)
通过家庭作业了解 Java 迭代器和通用数据结构。
我构建了一个双向链表 (LinkedList),它使用节点 (LinkedList$Node) 并有一个迭代器 (LinkedList$LinkedListIterator) 所有 classes 都使用泛型。
在 LinkedListIterator 的 @Overridden remove() 方法中,我正在使用外部方法-class,即 LinkedList class.
我收到以下编译时错误:
./LinkedList.java:170: deleteNode(LinkedList<T>.Node<T>,LinkedList<T>.Node<T>,LinkedList<T>.Node<T>) in LinkedList<T> cannot be applied to (LinkedList<T>.Node<T>,LinkedList<T>.Node<T>,LinkedList<T>.Node<T>)
deleteNode(nodeToBeRemoved, next, prev);
我的(原始)理解是类型不匹配,但我看不出这是怎么回事。
这是我的完整 class 代码:
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.ConcurrentModificationException;
public class LinkedList<T> implements Iterable<T> {
private Node<T> sentinel;
private long modCount; //apparently no unsigned int's in Java.
public LinkedList() {
modCount = 0;
sentinel = new Node<T>(null);
sentinel.setNext(sentinel);
sentinel.setPrev(sentinel);
}
public void append(T t) {
/*
APPEND:
...
[-----]
| |
[-1st-]
| |
inFront-> [SENTL]
| | <-- [newNode]
behind--> [-----]
| |
[-----]
...
*/
Node<T> newNode = new Node<T>(t);
Node<T> inFront = sentinel;
Node<T> behind = sentinel.prev();
//now actually insert:
insertNode(newNode, inFront, behind);
}
public void prepend(T t) {
/*
PREPEND:
...
[-----]
| |
inFront-> [-1st-]
| | <-- [newNode]
behind--> [SENTL]
| |
[-----]
| |
[-----]
*/
Node<T> newNode = new Node<T>(t);
Node<T> behind = sentinel;
Node<T> inFront = sentinel.next();
//now actually insert:
insertNode(newNode, inFront, behind);
}
public void removeHead() {
/*
REMOVE-FIRST:
...
inFront --> [-----]
| |
[-1st-] <-- *delete*
| |
behind ---> [SENTL]
| |
[-----]
| |
[-----]
...
*/
Node<T> inFront = sentinel.next().next();
Node<T> behind = sentinel;
Node<T> toDelete = sentinel.next();
// now actually delete
deleteNode(toDelete, inFront, behind);
}
private void insertNode(Node<T> newNode, Node<T> inFront, Node<T> behind) {
newNode.setNext(inFront);
newNode.setPrev(behind);
inFront.setPrev(newNode);
behind.setNext(newNode);
modCount++;
}
private void deleteNode(Node<T> toDelete, Node<T> inFront, Node<T> behind) {
inFront.setPrev(behind);
behind.setNext(inFront);
toDelete.setNext(null);
toDelete.setPrev(null);
modCount++;
}
@Override
public Iterator<T> iterator() {
return new LinkedListIterator<T>(sentinel);
}
/*
..:: MyIterator ::..
private inner class
*/
public class LinkedListIterator<T> implements Iterator<T> {
private Node<T> cursor;
private Node<T> lastReturned;
private long iterModCountPerspective;
public LinkedListIterator(Node<T> sentinel) {
cursor = sentinel.next();
lastReturned = null;
iterModCountPerspective = modCount;
}
private boolean hasBodhi() {
// bodhi: in Buddhism, bodhi is the understanding of the "true nature of things".
return (iterModCountPerspective == modCount);
}
@Override
public boolean hasNext() {
if (cursor == sentinel)
return false;
return true;
}
@Override
public T next() {
if (!this.hasNext()) {
throw new NoSuchElementException();
} else if (!hasBodhi()) {
throw new ConcurrentModificationException();
} else {
T aux = cursor.data();
lastReturned = cursor;
cursor = cursor.next();
return aux;
}
}
@Override
public void remove() {
//check we're allowed to remove:
if (lastReturned == null) {
throw new IllegalStateException();
}
if (!hasBodhi()) {
throw new ConcurrentModificationException();
}
//setup vars to perform deletion:
Node<T> nodeToBeRemoved = lastReturned;
Node<T> next = nodeToBeRemoved.next();
Node<T> prev = nodeToBeRemoved.prev();
// now delete
deleteNode(nodeToBeRemoved, next, prev);
iterModCountPerspective++;
//now setup vars for exit:
cursor = next;
lastReturned = null; // illegal to remove yet-again before first calling next()
}
}
/* ..:: Node ::..
private, compositional inner class
Interface:
void setNext(Node n) // change the Node in front of this Node
void setPrev(Node p) // change the Node behind this Node
Node next() // returns the Node in front of this Node
Node prev() // returns the Node behind this Node
T data() // returns the data stored inside this Node
*/
private class Node<T> {
private T data;
private Node<T> next;
private Node<T> prev;
public Node(T d) {
data = d;
next = null;
prev = null;
}
/*
METHOD setNext(Node<T> n)
This method takes the parameter Node
passed-in and puts it in front of this
Node.
input - Node n
output - none
eg: node4.setNext(node5);
*/
public void setNext(Node<T> n) {
next = n;
}
/*
METHOD setPrev(Node<T> n)
This method takes the parameter Node
passed-in and puts it behind of this
Node.
input - Node p
output - none
eg: node5.setPrev(node4);
*/
public void setPrev(Node<T> p) {
prev = p;
}
/*
METHOD next()
This method returns the Node in
front of this Node.
input - none
output - Node infront of this (this.next)
eg: Node nodeInFrontOfNode4 = node4.next();
*/
public Node<T> next() {
return next;
}
/*
METHOD prev()
This method returns the Node
behind of this Node.
input - none
output - Node behind of this (this.prev)
eg: Node nodeBehindOfNode4 = node4.prev();
*/
public Node<T> prev() {
return prev;
}
/*
METHOD data()
This method returns the data
inside of this Node.
input - none
output - Data inside of this Node
eg: PlanarShape shape4 = node4.data();
*/
public T data() {
return data;
}
}
}
Comp-sci 学生,第一次海报。 感谢所有 SO 专家。你曾多次帮助我和我的同龄人
发生这种情况,因为您在那里定义了 3 个不同的类型参数。每当您将 class 声明为:
class X<T> {}
... 你定义了一个新的类型参数 T
,无论是内部 class 还是外部 class。所以,在下面的场景中:
class X<T> {
class Y<T> {
}
}
两个 T's
是不同的。你可以这样做:
X<String> x = new X<String>();
Y<Double> y = x.new Y<Double>();
所以,这里考虑一个案例:
class X<T> {
public void helloThere(T obj) { }
class Y<T> {
// Ignore any syntactical error about method calling.
public void callHelloThere(T obj) {
helloThere(obj);
}
}
}
这肯定不适用于:
y.callHelloThere(2.5);
因为那样的话,您将 Double
类型传递给接受 String
的方法,因为您实例化了 X<String>
。
这与您在示例中遇到的情况相同。
解决方案?将 class Y<T>
更改为 class Y
,一切就绪。
通过家庭作业了解 Java 迭代器和通用数据结构。
我构建了一个双向链表 (LinkedList),它使用节点 (LinkedList$Node) 并有一个迭代器 (LinkedList$LinkedListIterator) 所有 classes 都使用泛型。
在 LinkedListIterator 的 @Overridden remove() 方法中,我正在使用外部方法-class,即 LinkedList class.
我收到以下编译时错误:
./LinkedList.java:170: deleteNode(LinkedList<T>.Node<T>,LinkedList<T>.Node<T>,LinkedList<T>.Node<T>) in LinkedList<T> cannot be applied to (LinkedList<T>.Node<T>,LinkedList<T>.Node<T>,LinkedList<T>.Node<T>)
deleteNode(nodeToBeRemoved, next, prev);
我的(原始)理解是类型不匹配,但我看不出这是怎么回事。
这是我的完整 class 代码:
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.ConcurrentModificationException;
public class LinkedList<T> implements Iterable<T> {
private Node<T> sentinel;
private long modCount; //apparently no unsigned int's in Java.
public LinkedList() {
modCount = 0;
sentinel = new Node<T>(null);
sentinel.setNext(sentinel);
sentinel.setPrev(sentinel);
}
public void append(T t) {
/*
APPEND:
...
[-----]
| |
[-1st-]
| |
inFront-> [SENTL]
| | <-- [newNode]
behind--> [-----]
| |
[-----]
...
*/
Node<T> newNode = new Node<T>(t);
Node<T> inFront = sentinel;
Node<T> behind = sentinel.prev();
//now actually insert:
insertNode(newNode, inFront, behind);
}
public void prepend(T t) {
/*
PREPEND:
...
[-----]
| |
inFront-> [-1st-]
| | <-- [newNode]
behind--> [SENTL]
| |
[-----]
| |
[-----]
*/
Node<T> newNode = new Node<T>(t);
Node<T> behind = sentinel;
Node<T> inFront = sentinel.next();
//now actually insert:
insertNode(newNode, inFront, behind);
}
public void removeHead() {
/*
REMOVE-FIRST:
...
inFront --> [-----]
| |
[-1st-] <-- *delete*
| |
behind ---> [SENTL]
| |
[-----]
| |
[-----]
...
*/
Node<T> inFront = sentinel.next().next();
Node<T> behind = sentinel;
Node<T> toDelete = sentinel.next();
// now actually delete
deleteNode(toDelete, inFront, behind);
}
private void insertNode(Node<T> newNode, Node<T> inFront, Node<T> behind) {
newNode.setNext(inFront);
newNode.setPrev(behind);
inFront.setPrev(newNode);
behind.setNext(newNode);
modCount++;
}
private void deleteNode(Node<T> toDelete, Node<T> inFront, Node<T> behind) {
inFront.setPrev(behind);
behind.setNext(inFront);
toDelete.setNext(null);
toDelete.setPrev(null);
modCount++;
}
@Override
public Iterator<T> iterator() {
return new LinkedListIterator<T>(sentinel);
}
/*
..:: MyIterator ::..
private inner class
*/
public class LinkedListIterator<T> implements Iterator<T> {
private Node<T> cursor;
private Node<T> lastReturned;
private long iterModCountPerspective;
public LinkedListIterator(Node<T> sentinel) {
cursor = sentinel.next();
lastReturned = null;
iterModCountPerspective = modCount;
}
private boolean hasBodhi() {
// bodhi: in Buddhism, bodhi is the understanding of the "true nature of things".
return (iterModCountPerspective == modCount);
}
@Override
public boolean hasNext() {
if (cursor == sentinel)
return false;
return true;
}
@Override
public T next() {
if (!this.hasNext()) {
throw new NoSuchElementException();
} else if (!hasBodhi()) {
throw new ConcurrentModificationException();
} else {
T aux = cursor.data();
lastReturned = cursor;
cursor = cursor.next();
return aux;
}
}
@Override
public void remove() {
//check we're allowed to remove:
if (lastReturned == null) {
throw new IllegalStateException();
}
if (!hasBodhi()) {
throw new ConcurrentModificationException();
}
//setup vars to perform deletion:
Node<T> nodeToBeRemoved = lastReturned;
Node<T> next = nodeToBeRemoved.next();
Node<T> prev = nodeToBeRemoved.prev();
// now delete
deleteNode(nodeToBeRemoved, next, prev);
iterModCountPerspective++;
//now setup vars for exit:
cursor = next;
lastReturned = null; // illegal to remove yet-again before first calling next()
}
}
/* ..:: Node ::..
private, compositional inner class
Interface:
void setNext(Node n) // change the Node in front of this Node
void setPrev(Node p) // change the Node behind this Node
Node next() // returns the Node in front of this Node
Node prev() // returns the Node behind this Node
T data() // returns the data stored inside this Node
*/
private class Node<T> {
private T data;
private Node<T> next;
private Node<T> prev;
public Node(T d) {
data = d;
next = null;
prev = null;
}
/*
METHOD setNext(Node<T> n)
This method takes the parameter Node
passed-in and puts it in front of this
Node.
input - Node n
output - none
eg: node4.setNext(node5);
*/
public void setNext(Node<T> n) {
next = n;
}
/*
METHOD setPrev(Node<T> n)
This method takes the parameter Node
passed-in and puts it behind of this
Node.
input - Node p
output - none
eg: node5.setPrev(node4);
*/
public void setPrev(Node<T> p) {
prev = p;
}
/*
METHOD next()
This method returns the Node in
front of this Node.
input - none
output - Node infront of this (this.next)
eg: Node nodeInFrontOfNode4 = node4.next();
*/
public Node<T> next() {
return next;
}
/*
METHOD prev()
This method returns the Node
behind of this Node.
input - none
output - Node behind of this (this.prev)
eg: Node nodeBehindOfNode4 = node4.prev();
*/
public Node<T> prev() {
return prev;
}
/*
METHOD data()
This method returns the data
inside of this Node.
input - none
output - Data inside of this Node
eg: PlanarShape shape4 = node4.data();
*/
public T data() {
return data;
}
}
}
Comp-sci 学生,第一次海报。 感谢所有 SO 专家。你曾多次帮助我和我的同龄人
发生这种情况,因为您在那里定义了 3 个不同的类型参数。每当您将 class 声明为:
class X<T> {}
... 你定义了一个新的类型参数 T
,无论是内部 class 还是外部 class。所以,在下面的场景中:
class X<T> {
class Y<T> {
}
}
两个 T's
是不同的。你可以这样做:
X<String> x = new X<String>();
Y<Double> y = x.new Y<Double>();
所以,这里考虑一个案例:
class X<T> {
public void helloThere(T obj) { }
class Y<T> {
// Ignore any syntactical error about method calling.
public void callHelloThere(T obj) {
helloThere(obj);
}
}
}
这肯定不适用于:
y.callHelloThere(2.5);
因为那样的话,您将 Double
类型传递给接受 String
的方法,因为您实例化了 X<String>
。
这与您在示例中遇到的情况相同。
解决方案?将 class Y<T>
更改为 class Y
,一切就绪。