Skip to content
June 12, 2011 / oop123

Urg, Why Are There So Many java.io Classes?

java.io is incredibly intimidating to beginners like me. There are hundreds of different classes (ok maybe I exaggerated, but there are still a lot of classes). This can easily put you off learning to use java.io (I know it did that to me). Once you understand how they work, however, it gets much less intimidating and easier to use.

Why Are There So Many Classes in Java.io?

To answer this you will have to know about design patterns. From wikipedia’s definition, “design pattern is a general reusable solution to a commonly occurring problem in software design”, which is just basically saying it’s an established pattern (i.e. way) of writing code that has been proven to lead to effective and maintainable code (i.e. cohesive and decoupled). They are very important and you should try to learn them as soon as possible.

The Java developers that wrote java.io felt like you should be able to customize how you want to get inputs and write outputs, so they employed the Decorator Pattern, a design pattern that allow you to add functionality to an existing object dynamically without editing the object’s class. To accomplish this, you wrap the object with a decorator class that contains the new functionality. An example from java.io would probably make this clearer (I suck at explaining things, sigh).

InputStream in = new BufferedInputStream(new FileInputStream("demo.txt"));
String str = readAllFromStream(in); //random utility method

FileInputStream allows you to read bytes from a file, but that’s the only thing it can do. For example, it doesn’t have buffering, which would make reading input more efficient. However, we can wrap it with a BufferedInputStream (by passing the FileInputStream in its constructor) to give it the functionality of buffering. However, this is not a pure Decorator pattern. To be a pure Decorator pattern, BufferedInputStream should not add any extra method like .readLine(). I’m going to just use another example to explain this.

InputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("demo.txt")));
int x = int.readInt(); //will throw exception

We just add the ability to read ints, long etc. to the input stream by wrapping it in DataInputStream. However, note that those functionality are implemented in methods not declared in the InputStream interface, so you will have to change to code to this for the code snippet to work:

DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream("demo.txt")));
int x = int.readInt(); //will work

Of course, any method that only use basic .read() will still function, and if you design your class well, you can add the new functionality without little to no refactoring.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: