📜  java observable to observer 堆栈溢出 - Java (1)

📅  最后修改于: 2023-12-03 14:42:15.593000             🧑  作者: Mango

Java Observable to Observer Stack Overflow

Introduction

In Java, the Observable class and the Observer interface provide a way for objects to communicate with each other using an event-driven architecture. The Observable class represents an object that can be observed, and the Observer interface represents objects that observe the state changes of the Observable object. However, if not used properly, this mechanism can lead to a stack overflow error.

Understanding Observable and Observer

The Observable class is part of the java.util package and provides methods for managing a list of observers and notifying them of any changes to the object. It can be extended by any class that needs to be observed.

The Observer interface is also part of the java.util package and must be implemented by any class that wants to observe changes in an Observable object. It contains a single method named update() that gets called when the observed object changes.

import java.util.Observable;
import java.util.Observer;

public class MyObservable extends Observable {
    public void doSomething() {
        // Perform some action
        setChanged();
        notifyObservers();  // Notify all observers
    }
}

public class MyObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        // Handle the update
    }
}
Stack Overflow Error

A stack overflow error occurs when the call stack, which keeps track of method calls, exceeds its maximum limit. In the context of observables and observers, a stack overflow error can happen if an observer directly or indirectly invokes the methods of the observed object, which triggers an infinite loop of updates.

Consider the following scenario:

import java.util.Observable;
import java.util.Observer;

public class MyObservable extends Observable {
    public void doSomething() {
        // Perform some action
        setChanged();
        notifyObservers();  // Notify all observers
    }
}

public class MyObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof MyObservable) {
            ((MyObservable) o).doSomething();  // Directly invoking the observed object's method
        }
    }
}

public class Main {
    public static void main(String[] args) {
        MyObservable observable = new MyObservable();
        observable.addObserver(new MyObserver());
        observable.doSomething();
    }
}

In this example, the update() method of MyObserver directly invokes the doSomething() method of the observed MyObservable object. This creates an infinite loop of updates, leading to a stack overflow error.

Avoiding Stack Overflow Error

To avoid a stack overflow error, it's crucial to ensure that the update() method of the observer does not directly or indirectly invoke methods of the observed object that trigger updates. Instead, the observer should only handle the update and perform any necessary actions unrelated to the observed object.

import java.util.Observable;
import java.util.Observer;

public class MyObservable extends Observable {
    public void doSomething() {
        // Perform some action
        setChanged();
        notifyObservers();  // Notify all observers
    }
}

public class MyObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        // Handle the update, but don't invoke observed object's methods
    }
}

public class Main {
    public static void main(String[] args) {
        MyObservable observable = new MyObservable();
        observable.addObserver(new MyObserver());
        observable.doSomething();
    }
}

By following this approach, the stack overflow error can be avoided, and the observable-observer mechanism can function correctly.

Conclusion

The Java observable-observer mechanism provides a powerful way for objects to communicate using events. However, it's essential to be mindful of potential stack overflow errors caused by incorrect usage of the mechanism. By ensuring that observers don't directly or indirectly invoke methods of the observed object in the update() method, the mechanism can work as intended without any issues.