Java gravel of the day: Must write to a stream

jdavidb on 2008-02-07T20:47:31

Java seems bound and determined to often make it difficult to get certain pieces of text. I guess since Java's not a text-slinging language, it simply never occurred to some designers of common interfaces that you might want to obtain, inspect, and/or manipulate certain pieces of text for use by your program rather than simply throwing them to a stream (which you may or may not even get to choose). It's like there's little holes in their brains where that idea should have been presented to them.

Look at the very foundations of the language in exception-handling: there's a printStackTrace() method. But there's no method to return the text provided by printStackTrace so that I can do something else with it. I'm sure some day I'll learn how to get (or produce, sigh...) that text myself, but it ought to be easy. I mean, what if I'd like it to go to standard error instead of standard out? (Or the other way around; I forget where it goes.)

Strangely, there's actually a piece of standard Java functionality that does seem to support getting such needed pieces of text: toString(). But the problem is that because of the aforementioned Java-induced holes in the brain, the brilliance of this design feature has eluded lots and lots of library implementors: toString() may or may not return a useful textual representation of something when one exists. Sometimes it's no better than stringifying a blessed Perl hash. Great job trying to get around Java's inability to stringify things, but unfortunately the memo about the good this could do didn't make it out.

So here I am with an XML document object. What's the obvious implementation for toString()? Um ... turn it into XML? Of course not!!! If you want to turn your XML object into XML, you'll need a special magic helper class for that. And can your special magic helper class just give you a straightforward String containing the textual representation of your XML? No, it can not. Your options are to put it in a stream, or forget it. Look, buddy, you should be thankful we don't just println() it to System.out.

I recognize that XML can be very, very long, and that taking an already large XML object and serializing it into a very long String in the same memory space may be a bad idea. But my XML object is small. And I think there's some brilliant Java mechanism for handling things that ought to work like that but sometimes don't. I think it's called Acceptations or something.

I think another thing about Java that contributed to the mindset that thinks providing constructors for four different types of streams, but no means of outputting to a String, is a normal idea is the sheer difficulty in Java of opening up a file and performing output on it. It's way, way too many steps. And even outputting to the console is more difficult than it "should" be, requiring you to reference an object when most other programming languages provide a command to Just Do It. (But Java gets points for academic cleanness of design, here.)

There's workarounds for everything, of course. You can trick Java into using something else for standard output for awhile, if you're forced into that. And I'm sure there's a way to wrap seven layers of output streams on top of a scalar -- I mean a String -- and force something to convert to a String. But really this should not be that difficult.