What exactly do MediaPlayer.play()
and MediaPlayer.stop()
do?-- are they event listeners for user input or are they actually methods which start some sort of media stream on the system? If all they are are listeners for user input, then it's perfectly reasonable for them to do nothing (although it would be a good idea to at least log them somewhere). However, if they affect the model your UI is controlling, then they could throw an IllegalStateException
because the player should have some sort of isPlaying=true
or isPlaying=false
state (it needn't be an actual Boolean flag like written here), and so when you call MediaPlayer.stop()
when isPlaying=false
, the method can't actually "stop" the MediaPlayer
because the object isn't in the appropriate state to be stopped -- see the description of the java.lang.IllegalStateException
class:
Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
Why throwing exceptions can be good
A lot of people seem to think that exceptions are bad in general, as in they should never be thrown (cf. Joel on Software). However, say you have a MediaPlayerGUI.notifyPlayButton()
which calls MediaPlayer.play()
, and MediaPlayer.play()
invokes a bunch of other code and somewhere down the line it interfaces with e.g. PulseAudio, but I (the developer) don't know where because I didn't write all that code.
Then, one day while working on the code, I click "play" and nothing happens. If MediaPlayerGUIController.notifyPlayButton()
logs something, at least I can look into the logs and check that the button click was in fact registered... but why doesn't it play? Well, say there's in fact something wrong with the PulseAudio wrappers which MediaPlayer.play()
invokes. I click the "play" button again, and this time I get an IllegalStateException
:
Exception in thread "main" java.lang.IllegalStateException: MediaPlayer already in play state.
at org.superdupermediaplayer.MediaPlayer.play(MediaPlayer.java:16)
at org.superdupermediaplayer.gui.MediaPlayerGUIController.notifyPlayButton(MediaPlayerGUIController.java:25)
at org.superdupermediaplayer.gui.MediaPlayerGUI.main(MediaPlayerGUI.java:14)
By looking at that stack trace, I can ignore everything before MediaPlayer.play()
when debugging and spend my time figuring out why e.g. no message is being passed to PulseAudio to start an audio stream.
On the other hand, if you don't throw an exception, I'll have nothing to start working with other than: "The stupid program doesn't play any music"; Although not as bad as explicit error hiding such as actually swallowing an exception which was in fact thrown, you're still potentially wasting others' time when something does go wrong... so be nice and throw an exception at them.