【问题标题】:Java: Generic Class ExceptionJava:通用类异常
【发布时间】:2012-05-30 06:32:22
【问题描述】:

我正在设计一个通用链表来创建字符串的链表。
但是我不断收到此错误:

Exception in thread "main" java.lang.NoSuchMethodError: Node.<init>(Ljava/lang/Object;)V
at LinkedList.addNode(LinkedList.java:10)
at LinkedList.<init>(LinkedList.java:22)
at Trial.main(Trial.java:7)


从堆栈跟踪中,错误是在 LinkedList 的 addNode() 方法中生成的。我包括此方法的定义以及 Node 类的定义。
LinkedList addNode()

public void addNode(T n) {
        Node<T> temp = new Node<T>(n);
        if(start==null) {
            start = temp;
            current = start;
        } else {
            end.setNext(temp);
        }
        end =temp;
    }


Node.java

public class Node<T>{
private T n;
Node next;
Node(T n) {
    this.n = n;
    next = null;
}
public void setNext(Node nextNode) {
    next = nextNode;
}
public Node getNext() {
    return next;
}
public T getN() {
    return n;
}
@Override
public String toString() {
    if(n instanceof String)
        return n.toString();
    else {
        return T.toString();
    }
}

}



LinkedList.java

public class LinkedList<T>{
Node start;
Node end;
Node current;
private static final long serialVersionUID = 901L;
    LinkedList(T n) {
        addNode(n);
    }
    public void addNode(T n) {
        Node<T> temp = new Node<>(n);
        if(start==null) {
            start = temp;
            current = start;
        } else {
            end.setNext(temp);
        }
        end =temp;
    }

    LinkedList(T[] n) {
        for(T print : n)
        addNode(print);
    }
    public void addNode(T[] n) {
        if(n!=null) {
            for (T values : n) {
                addNode(values);
            }
        }
    }

    public void incC() {
        current = current.getNext();
    }
    public void insert(T n) {
        Node newNode = new Node(n);
            if(current==start){
                newNode.setNext(current);
                start = newNode;
            }else {
                Node tempstart = start;
                Node prevAdd=null;
                while(tempstart!=current){
                    prevAdd = tempstart;
                    tempstart = tempstart.getNext();
                }
                prevAdd.setNext(newNode);
                newNode.setNext(current);
            }
    }

    public void find(T x) {
        Node tempstart;
        tempstart = start;
        while (tempstart!=null) {
            if(tempstart.getN()==x) {
                System.out.println("Element found");
                tempstart = tempstart.getNext();
            } else {
                tempstart = tempstart.getNext();
            }
        }
    }
    public void delete(T x) {
        Node previous=null;
        Node tempstart = start;
        while(tempstart!=null) {
        if(tempstart.getN()==x) {
            if(previous ==null) {
                previous = tempstart;
                tempstart = tempstart.getNext();
                start = tempstart;
                previous.setNext(null);
                previous = null;
            } else {
                tempstart = tempstart.getNext();
                previous.setNext(tempstart);
            }
        }else {
            previous = tempstart;
            tempstart = tempstart.getNext();
        }
        }
    }
    @Override
    public String toString() {
        Node tempNode = start;
        String str = "Values: ";
        while (tempNode!=null) {
            str = str + " " + tempNode.toString();
            tempNode = tempNode.getNext();
        }
        return str;
    }
}

Trial.java

public class Trial {
public static void main(String[] args) {
    String[] para = {"Hollo","this","is","me"};
    LinkedList<String> L1;
    L1 = new LinkedList<String>(para);
    System.out.println(L1);
}

【问题讨论】:

  • 你能在调用 LinkedList 的 Trial.main(...) 中分享你的代码

标签: java generics exception singly-linked-list


【解决方案1】:
return T.toString();

这不起作用。 T 是一个类型变量,由于类型擦除,仅在编译时可用。

但除此之外,我看不出有什么问题,您需要从 LinkedList 类中发布更多代码。

【讨论】:

  • @Sean 好吧,如果我要创建一个整数链接列表,那么我会要求这样做,不是吗?发布此内容后,我稍微更改了代码。现在看起来像这样 ublic String toString() { if(n instanceof String) return n.toString();否则 { 返回 T.toString(n); } }
  • @FasihKhatib 不,只写return n.toString() 或空安全:return String.valueOf(n)
  • 好的,我将编辑帖子以包含 LinkedList.java 的整个定义
  • T.toString() 不起作用。几乎可以肯定,在所有情况下,您都应该返回 n.toString()
【解决方案2】:

您应该将LinkedList&lt; T &gt; 中的startendcurrent 字段以及Node&lt; T &gt; 中的next 字段声明为Node&lt; T &gt; 类型,而不是Node。不要在代码中的任何地方使用原始类型,因为它们会转换为 Node&lt; Object &gt;

【讨论】:

  • 这为我解决了,但是先生,我有一个问题。为什么 Node 类中的下一个不是用 定义的,并且只在 LinkedList
  • @FasihKhatib,很抱歉,我没有听懂你的问题。你消除了所有 Node 的原始提及吗?
  • 是的,我用 Node 替换了 Node 的每个实例 :) 嗯...你有关于 Generic 类这个主题的简单练习吗?我想多练习一点 0:)
  • 基元将被“自动装箱”。如果您使用42 之类的原语调用某个泛型方法f( T t ),Java 将推断参数的类型Integer(而不是int)。
【解决方案3】:

您的课程Node没有编译,因此您可能应该先解决该问题,然后再继续:

return T.toString();

没有意义。大概就是这么写吧:

return n.toString();

现在已经足够了。

【讨论】:

  • @FasihKhatib 然后编辑您的问题并发布 LinkedList 的完整代码。
  • @FasihKhatib 我刚刚运行您的代码没有问题。我只用public String toString() { return n.toString();} 替换了你的 Node.toString() 并且我可以毫无问题地运行它。你确定你已经正确地重新编译了你的类吗?
  • 是的,先生。我使用 JCrestor LE,所以所有与 Trial.java 关联的类(它具有创建链表的 main() 方法)所以我不必手动执行任何操作
  • 我相信 Node temp = new Node(n); 是错误。会不会?
  • @FasihKhatib 您得到的错误是带有Object 参数的构造函数节点不存在(但实际上在JVM 的类路径中找到了Node 类)。由于您的代码实际上包含该构造函数,因此我怀疑您在编写 toString 方法时尚未重新编译您的类。也许在您的项目上尝试“清洁”
【解决方案4】:

在Node.java中,在方法中

@Override 
public String toString() { 
    if(n instanceof String) 
        return n.toString(); 
    else { 
        return T.toString(); 
    } 
} 

// 下面的语句会导致编译错误。 返回 T.toString();

【讨论】:

  • @JackAss 我什至试过 return n.toString();但它仍然给出了那个错误。可能跟 Node.java 的构造函数有关
  • toString() 通常是非静态方法。因此,如果 T 是一个类,则 T.toString() 意味着该类必须具有默认的 toString() 作为静态。但事实并非如此。因此编译错误。如果你默认使用任何类,它会扩展 Object 类,因此你会得到非静态的 toString()。因此 n.toString() 有效,而 T.toString() 导致编译失败
  • 我删除了该语句,所以现在只有 n.toString() 但仍然存在错误。我定义 Node.java 类的方式可能有错误吗?
  • public void addNode(T n) { Node temp = new Node(n);如果(开始==空){开始=临时;当前=开始; } else { end.setNext(temp); } 结束 = 温度; } 这里 Node temp = new Node(n);不是一个有效的陈述。
  • @JackAss 那么我该如何修改呢? Node 是一个独立的类,它封装了 List 的数据元素,并且有一个指向下一个的指针。请告诉我为什么这是一个错误以及如何解决它
【解决方案5】:

您的Node 构造函数不是public,因此如果您从另一个包中的类调用它,它将不起作用。

【讨论】:

  • 只要所有源文件都在同一个目录下,构造函数就可以工作:)
猜你喜欢
  • 2016-01-08
  • 2014-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 2011-02-07
相关资源
最近更新 更多