我只是在日食Juno IDE上用Java编写了一个非常简单的“Stack”类,它有2个操作 - 推送和弹出。我在pop()方法中的一个检查是查看堆栈是否为空;如果是这样,我抛出一个NoSuchElementException。因此,如果我按顺序推1,2,3,4,5然后弹出元素五次,我希望看到按顺序打印5,4,3,2,1。但是在添加了五个元素后,如果我故意尝试将堆栈弹出SIX次,我会期望5,4,3,2,1,然后是NoSuchElementException。
在我的情况下发生的事情是控制台随意打印出NoSuchElementException(即在打印出5,4,3,2,1之后并不总是;有时会打印出来:
stack pop: 5
stack pop: 4
Exception in thread "main" java.util.NoSuchElementException: Stack Underflow
stack pop: 3
stack pop: 2
stack pop: 1
at Stack.pop(Stack.java:29)
at Stack.main(Stack.java:47)
有时打印出来:
Exception in thread "main" stack pop: 5
stack pop: 4
stack pop: 3
stack pop: 2
stack pop: 1
java.util.NoSuchElementException: Stack Underflow
at Stack.pop(Stack.java:29)
at Stack.main(Stack.java:47)
我的目标是了解管理此行为的原因。由于我正在使用print语句(而不是一个可能在下面有类似队列的实现的记录器),我希望按顺序看到这些语句,但我怀疑这里有一些并发性。以下是我的代码:
import java.util.NoSuchElementException;
public class Stack {
private Node first;
private int size;
private class Node{
Node next;
int value;
}
public Stack(){
size=0;
first=null;
}
public void push(int x){
Node previousFirst = first;
first = new Node();
first.value = x;
first.next = previousFirst;
size++;
}
public int pop(){
if(first == null){
throw new NoSuchElementException("Stack Underflow");
}
int poppedNodeVal = first.value;
first = first.next;
size--;
return poppedNodeVal;
}
public static void main(String[] args) {
Stack stack1 = new Stack();
stack1.push(1);
stack1.push(2);
stack1.push(3);
stack1.push(4);
stack1.push(5);
for(int i=5; i>=0;i--){
System.out.println("stack pop: " + stack1.pop());
}
}
}
关于如何可靠地打印出来的任何想法,更重要的是,在控制台中可能导致异常打印异常的原因是什么?
答案 0 :(得分:3)
这是因为System.err和System.out不是同一个流,有时会发生它们未同步的情况。 System.err用于例外,System.out就是您使用的。
也许你想尝试这样的事情:
System.setErr(System.out);
Thiw会将标准System.err路由到System.out 现在你应该有正确的5,4,3,2,1,异常流程。
显然,如果两个流分离是有原因的,那么你可以做我告诉你的事情但是在测试期间要小心(比如在jUnit中)
答案 1 :(得分:2)
您的异常未被捕获,因此会停止执行程序。问题可能是
a)您正在插入5个元素并提取6,将您的循环更改为
for(int i = 5; i >0; i--)
b)在执行了所有5个元素的System.out.println
之后抛出异常(否则这些行根本不会打印,因为程序退出)。但部分内容尚未打印到控制台(它有一个缓冲区)。当异常中断时,它会打印到System.err
(不同的缓冲区),因为在您的情况下,System.out
和System.err
在控制台中结束,您将获得混合内容。
将for
包裹在try/catch
块中并拦截例外。打印一条消息给System.out
通知它。您将看到它在打印最后一个元素之前出现。
答案 2 :(得分:2)
您的邮件正在使用System.out
,但例外情况会打印在System.err
上。 Eclipse控制台不会同步这两个流,因此它们可能无序地出现在控制台上。尝试将您的消息输出到System.err
,它们应该按顺序排列。