如何在线程“main”java.lang.StackOverflowError中找到Exception的原因

时间:2013-03-24 04:33:02

标签: java

要运行我的代码,只需将其复制并粘贴到IDE中 - 一切都在那里。这是一个使用Observer-Observable设计模式的飞行监控程序。 FlightStautsMonitor是Observer,用于监控Flight的航班状态(整数)。 FlightStatusChangeEvent是一个记录航班状态变化的类。 Demo是驱动程序类,或者是main类。

我的问题是我不确定我是否使用Observer和Observable API。我收到运行时错误的输出 -

Old flight status
F:1, S: 0
F:2, S: 0
F:3, S: 0
F:4, S: 0
F:5, S: 0
Exception in thread "main" java.lang.StackOverflowError
at java.util.Vector.toArray(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at demo.Flight.updateStatus(Demo.java:40)
at demo.FlightStatusMonitor.update(Demo.java:91)
at java.util.Observable.notifyObservers(Unknown Source)

问题的原因是什么?如何修复此代码?

//package demo;

import java.util.*;

class FlightStatusChangeEvent{

int status;
Flight flight;

FlightStatusChangeEvent(int statusCode, Flight flight){

    this.status = statusCode;
    this.flight = flight;

}

public int getStatus(){return this.status;}

public Flight getFlight(){return this.flight;}


}

class Flight extends Observable{

int status;// 0 = on time, -1 = late, +1 = before scheduled time
String flightCode;

Flight(String flightCode){

    this.flightCode = flightCode;

}

public void updateStatus(int statusCode){

    this.status = statusCode;
    FlightStatusChangeEvent fsce = new FlightStatusChangeEvent(status, this);
    setChanged();
    notifyObservers(fsce);

}


public String getFlightCode(){return this.flightCode;}

public String toString(){return "F:" + flightCode + ", S: " + status;}

}


 class FlightStatusMonitor implements Observer{

public static ArrayList<Flight> flights = new ArrayList<Flight>();

static{

    for(int i = 1; i < 6; i++){

        Flight ff = new Flight("" + i);
        flights.add(ff);        
    }

}

//keep calling this method every 10 sec to get latest flight status
public static void displayStatusOfFlights(){

    //print all flight statuses in array list - flights
    for(Flight fl : flights){
        System.out.println(fl);

    }

}

public void update(Observable flight, Object flightStatusEvent){

    FlightStatusChangeEvent fsce = (FlightStatusChangeEvent) flightStatusEvent;     
    Flight fl = fsce.getFlight();
    String code = fl.getFlightCode();
    int status = fsce.getStatus();

    //find the flight in array flights and then update its status
    for(int i = 0; i < flights.size(); i++){

        Flight fli = flights.get(i);
        String flCode = fli.getFlightCode();

        if(flCode.equals(code)){
            fli.updateStatus(status);
            System.out.print("Flight status updated !");

            break;

        }

    }


}

}


 public class Demo{

public static void main(String[]args){

    FlightStatusMonitor fsm = new FlightStatusMonitor();
    System.out.println("Old flight status");
    ArrayList<Flight> fllist = fsm.flights;
    fsm.displayStatusOfFlights();

    for(Flight fl : fllist ){

        fl.addObserver(fsm);

    }

    fsm.flights.get(1).updateStatus(-1);
    System.out.println("New flight status");        
    fsm.displayStatusOfFlights();

}


}

2 个答案:

答案 0 :(得分:3)

Flight.updateStatus正在调用notifyObersevers

FlightStatusMonitor#update正在调用flights.get(x).updateStatus ...开始减少结束。

不更新从所述对象收到的事件通知中的对象状态...

这是堆栈跟踪的关键部分:

Exception in thread "main" java.lang.StackOverflowError
    at java.util.Arrays.copyOf(Arrays.java:2219)
    at java.util.Vector.toArray(Vector.java:687)
    at java.util.Observable.notifyObservers(Observable.java:154)
    at teststackoverflow.Demo$Flight.updateStatus(Demo.java:73)
    at teststackoverflow.Demo$FlightStatusMonitor.update(Demo.java:125)
    at java.util.Observable.notifyObservers(Observable.java:159)
    at teststackoverflow.Demo$Flight.updateStatus(Demo.java:73)
    at teststackoverflow.Demo$FlightStatusMonitor.update(Demo.java:125)

您可以(从底部开始),FlightStatusMonitor.update正在呼叫Flight#updateStatus,呼叫Observable.notifyObservers,呼叫FlightStatusMonitor.update

我建议您在调试标志设置为true(javac -g)的情况下编译代码

更新了可能的修复

所以,我认为,你需要做的不仅是比较航班代码,还要比较每个航班的航班状态,只改变那些状态不匹配的航班状态

public void update(Observable flight, Object flightStatusEvent) {

    FlightStatusChangeEvent fsce = (FlightStatusChangeEvent) flightStatusEvent;
    Flight fl = fsce.getFlight();
    String code = fl.getFlightCode();
    int status = fsce.getStatus();

    //find the flight in array flights and then update its status
    for (int i = 0; i < flights.size(); i++) {

        Flight fli = flights.get(i);
        String flCode = fli.getFlightCode();

        if (flCode.equals(code)) {
            //** Possible Fix **//
            if (fli.status != fl.status) {
                fli.updateStatus(status);
                System.out.print("Flight status updated !");
            }
        }
    }
}

答案 1 :(得分:3)

发生堆栈溢出时会抛出

StackOverflowError,因为应用程序过于冗长。

您的问题出在update方法中。 您正在调用updateStatus方法,updateStatus方法会再次调用update。 删除fli.updateStatus(status);将解决您的问题。

public void update(Observable flight, Object flightStatusEvent) {

        FlightStatusChangeEvent fsce = (FlightStatusChangeEvent) flightStatusEvent;
        Flight fl = fsce.getFlight();
        String code = fl.getFlightCode();
        int status = fsce.getStatus();

        // find the flight in array flights and then update its status
        for (int i = 0; i < flights.size(); i++) {

            Flight fli = flights.get(i);
            String flCode = fli.getFlightCode();

            if (flCode.equals(code)) {
                // THIS WILL CAUSE STACKOVERFLOWERROR
                fli.updateStatus(status);
                System.out.print("Flight status updated !");

                break;

            }

        }

    }