In addition to all the numerous answers here, I'd just like to add that throwing an exception is costly. Although the Java VM has improved so much over the years that this cost can be considered negligible, it would still be something you might want to optimize.
I'll cite another related SO question on the cost of throwing exceptions and the performance analysis created. these answers are more thorough than I can write here regarding the specifics of Java.
In short though, the throwing of exceptions is costly mainly because the machine has to unwind from the stack trace, and that information about the stack trace will always be recorded, even if it is not used, disrupting the flow of logic. A basic principle would be to put functions that might throw an exception in a try-catch block, so that the program knows how to handle itself and not crash. (users wouldn't like to see exceptions at all).
That being said, if you can choose to not throw an exception, don't do it, for performance. This is also in line with Steve McConnell's principle of exceptions in his Code Complete book, that is, only throw exceptions if they are truly exceptional.
For this particular case of the disconnect function, if you feel that having a null
value is something that doesn't happen often, then throw the exception. However, if it is something that happens regularly (such as say a user not entering a value in a field, don't want an exception for that), return a false, or even handle the case within that same method, after all if the function serves to disconnect something, and it should be able to do that for all cases that happen often (already disconnected, connection dead, no reply from server etc), and only exceptions for specific cases like 2 instances of your program running, race conditions etc.