要运行我的代码,只需将其复制并粘贴到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();
}
}
答案 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;
}
}
}