java - 为什么当参数和参数匹配时会发生 javac 错误 "(x) cannot be applied to (y)"? (内部类调用外部类方法)

标签 java compiler-errors iterator inner-classes iterable

通过作业学习 Java 迭代器和通用数据结构。

我构建了一个双向链表 (LinkedList),它使用节点 (LinkedList$Node) 并有一个迭代器 (LinkedList$LinkedListIterator) 所有类都使用泛型。

在 LinkedListIterator 的 @Overridden remove() 方法中,我正在使用外部类的方法,即 LinkedList 类。

我收到以下编译时错误:

./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);

我的(原始)理解是类型不匹配,但我看不出这是怎么回事。

这是我的完整类代码:

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 X<T> {}

...你定义了一个新的类型参数T ,无论是内部类还是外部类。所以,在下面的场景中:

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 - 为什么当参数和参数匹配时会发生 javac 错误 "(x) cannot be applied to (y)"? (内部类调用外部类方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36832650/

相关文章:

java - Tomcat 7 : The requested resource is not available

java - 使用泛型、数组和compareTo()时出错

c - GSL 多个错误处理程序定义链接时出错

python - 迭代和连接 2 个列表占用大量内存

javascript - 迭代状态变量

java - 使用spark-cassandra-connector时出错: java. lang.NoSuchMethodError

java - Android:SharedPreferences 有时会导致 NullPointEreException 错误

java - Maven包错误

java - 标记上的语法错误、结构错误 - 二分搜索方法中的错误

java - java中的通用迭代器实现