Subject that emits the most recent item it has observed and all subsequent observed items to each subscribed
Observer.
This subject does not have a public constructor by design; a new empty instance of this
BehaviorSubject can be created via the
#create() method and
a new non-empty instance can be created via
#createDefault(Object) (named as such to avoid
overload resolution conflict with
Observable.create that creates an Observable, not a
BehaviorSubject).
Since a
Subject is conceptionally derived from the
Processor type in the Reactive Streams specification,
nulls are not allowed (Rule 2.13) as
default initial values in
#createDefault(Object) or as parameters to
#onNext(Object) and
#onError(Throwable). Such calls will result in a
NullPointerException being thrown and the subject's state is not changed.
Since a
BehaviorSubject is an
io.reactivex.Observable, it does not support backpressure.
When this
BehaviorSubject is terminated via
#onError(Throwable) or
#onComplete(), the
last observed item (if any) is cleared and late
io.reactivex.Observers only receive
the respective terminal event.
The
BehaviorSubject does not support clearing its cached value (to appear empty again), however, the
effect can be achieved by using a special item and making sure
Observers subscribe through a
filter whose predicate filters out this special item:
BehaviorSubject<Integer> subject = BehaviorSubject.create();
final Integer EMPTY = Integer.MIN_VALUE;
Observable<Integer> observable = subject.filter(v -> v != EMPTY);
TestObserver<Integer> to1 = observable.test();
observable.onNext(1);
// this will "clear" the cache
observable.onNext(EMPTY);
TestObserver<Integer> to2 = observable.test();
subject.onNext(2);
subject.onComplete();
// to1 received both non-empty items
to1.assertResult(1, 2);
// to2 received only 2 even though the current item was EMPTY
// when it got subscribed
to2.assertResult(2);
// Observers coming after the subject was terminated receive
// no items and only the onComplete event in this case.
observable.test().assertResult();
Even though
BehaviorSubject implements the
Observer interface, calling
onSubscribe is not required (Rule 2.12)
if the subject is used as a standalone source. However, calling
onSubscribeafter the
BehaviorSubject reached its terminal state will result in the
given
Disposable being disposed immediately.
Calling
#onNext(Object),
#onError(Throwable) and
#onComplete()is required to be serialized (called from the same thread or called non-overlappingly from different threads
through external means of serialization). The
#toSerialized() method available to all
Subjects
provides such serialization and also protects against reentrance (i.e., when a downstream
Observerconsuming this subject also wants to call
#onNext(Object) on this subject recursively).
This
BehaviorSubject supports the standard state-peeking methods
#hasComplete(),
#hasThrowable(),
#getThrowable() and
#hasObservers() as well as means to read the latest observed value
in a non-blocking and thread-safe manner via
#hasValue(),
#getValue(),
#getValues() or
#getValues(Object[]).
Scheduler:
BehaviorSubject does not operate by default on a particular
io.reactivex.Scheduler and
the
Observers get notified on the thread the respective
onXXX methods were invoked.
Error handling:
When the
#onError(Throwable) is called, the
BehaviorSubject enters into a terminal state
and emits the same
Throwable instance to the last set of
Observers. During this emission,
if one or more
Observers dispose their respective
Disposables, the
Throwable is delivered to the global error handler via
io.reactivex.plugins.RxJavaPlugins#onError(Throwable) (multiple times if multiple
Observers
cancel at once).
If there were no
Observers subscribed to this
BehaviorSubject when the
onError()was called, the global error handler is not invoked.
Example usage:
// observer will receive all 4 events (including "default").