Archive

Archive for the ‘Java’ Category

Picking the right IO class

May 8th, 2009

Choosing the right class for IO is not always obvious. Java offers several levels of abstraction.

At the most basic level are streams of bytes. That is raw data. There is two kind of streams, input and output streams. There are two major resource kind, files and byte arrays. (We will come back on that below, when we talk about testing.)

new FileInputStream(filename);
new ByteArrayInputStream(bytes);
new FileOutputStream(filename);
new ByteArrayOutputStream();

To get the result of a byte array output stream, call its #toString method.

If you work with text, you should use readers and writers. They know how to encode characters as bytes and vice versa. There are different character encodings, of which ISO-8859-1 and UTF-8 are the most important. Whenever possible you should use UTF-8.

To create a reader, wrap it around an input stream. To create a writer, wrap it around an output stream.

new InputStreamReader(new FileInputStream(filename), "UTF-8");
new InputStreamReader(new ByteArrayInputStream(bytes), "UTF-8");
new OutputStreamWriter(FileOutputStream(filename), "UTF-8");
new OutputStreamWriter(ByteArrayOutputStream(), "UTF-8");

Plus there are two special classes to work with strings.

new StringReader(string);
new StringWriter();

To get the result of a string writer, just call its #toString method.

If you write to a file all characters are immediately written to disk. This is slow. It’s much faster to first write to a buffer, and only flush its content to disk when to buffer is full. The same applies for reading. Therefore, there are additional wrappers that buffer the underlying stream.

new BufferedReader(new InputStreamReader(stream));
new BufferedWriter(new OutputStreamWriter(stream));

If you work with binary data, you can either use a random access file or one of data input and data output stream. Random access files are called random access file, because they dont stream over the file but always provide access to any position within the file. Like a chunk of memory.

new RandomAccessFile(filename);
new DataInputStream(stream);
new DataOutputStream(stream);

(Random access file are a rather modern invention, for example my very first computer still used a tape as disk – yes the same as your beloved Kasperlikasette – and thus random access was technically impossible. Plus no harddisk, no mouse, no graphical user interface, no file system, no color screen, just 320 on 200 monochrome pixels, 1 Mhz slow, and only 64k memory. But lots of fun.)

How to test file access?

Typically your program will read and write to files. However, tests should not creates files but rather work in-memory only. This can be done using the byte array streams instead of the files streams.

akuhn Java

Howto turn off System.out

April 26th, 2009

System.out is handy for quick and dirty debugging, but sometime you want to turn it of.

There are three solutions

  1. Have an output object that you pass to all methods that do printing. Make two implementation of class Out, a class Verbose that prints to the console and a class Silence that does not print.

    public interface Out {
        public void put(String text);
    }
    
    public class Whatever {
        public void method(Out out, Object... args) {
            ...
            out.put("Hic sunt leones.");
            ...
        }
    }
    
    Out out = new Verbose();
    new Whatever().method(out, ...);
    
  2. Have static method that uses a static flag to switch between printing and silence.
    public class Out {
        public static boolean SILENT = true;
        public static void put(String text) {
            if (!SILENT) System.out.println(text);
        }
    }
    
    public class Whatever {
        public void method(Object... args) {
            ...
            Out.put("Hic sunt leones.");
            ...
        }
    }
    
    Out.SILENCE = false;
    new Whatever().method(...);
    
  3. Redirect the standard output to custom PrintStream instance. I wont go into details here, because this is black magic. But it is good to know that this can be done, for example to silence a third-party library. (In case you want to take this path, see the API documentation of System#setOut)

akuhn Java

Howto Create An Instance with Reflection

April 25th, 2009

Using reflection you can, not only invoke methods, but also create an instance of a class.

String className = "java.util.ArrayList";
Class javaClass = Class.forName(className);
Object instance = javaClass.newInstance();

akuhn Java

Arrays considered harmful

April 20th, 2009

Java offers to kind of containers, arrays and collections.

As a rule, you should always prefer collections. Collections offer a higher level of abstractions. The way arrays are realized in Java is a reminiscence of lower level languages, as for example C. The role of arrays in Java is not for end-user application programmer but for building of high-level library constructions.

Arrays do not follow Java’s usual semantics, they neither are full objects nor do they have real classes. They do not have a meaningful toString() output. They have a final length field instead of a size() method. They offer no useful methods beside that. You cannot implement your own array classes. And worst, their type system is broken. You can assign an A[] array to a B[] array if B is a subtype of A (called covariance), and thus bad things may happen

Object[] array = new String[10];
array[3] = new Square();

The above code fails at runtime with an ArrayStoreException because you try to store a square in an array of strings. Collections avoid this problem (even though generics aren’t without pitfalls either).

You should not return an array as the value of a public method or property. If an Object returns an array, it exposes its internal state because an array is always mutable. Client can modify the array and thus peek and poke the internal state of your object. This violates encapsulation!

The same problem arises when returning a collection, just here we can do either of two things: return an immutable collection, or (even better) return an iterable. Recall that the caller is requesting values, not variables. And typically even, the caller will just enumerate over the values rather than accessing them by index. Thus the best practice is:

class Folder {
    private List<File> files;
    public Iterable<File> files() {
        return files; // list implements iterable, lucky us
    }
    public int filesCount() {
        return files.size();
    }
}

Method files() returns the files as a stream of values rather than by index. Clients can only enumerate over the values, for example using a for loop, but not modify the underlying collection (ignoring iterator’s unlucky remove method #java #fail). An iterable is a factory for iterables, thus the client can even iterate multiple times over the collection. Basically, we what return is a view on the collection where only its iterator() method is visible. (Of course, they could still cast it to a list, but this is considered very bad style in static typing world).

(parts via Eric Lippert and Reinier Zwitserloot and rssh)

akuhn Java, Patterns, Uncategorized

Hidden Features of Java

April 18th, 2009

Just stumbled upon this, Hidden Features of Java.

akuhn Java, Read this!

Guard Clause and other Implementation Patterns

April 15th, 2009

While programs have a main flow, some situations require deviations from the
main flow. The guard clause is a way to express simple and local exceptional
situations with purely local consequences. Compare the following:

void initialize() {
    if (!isInitialized()) {
        ...
    }
}

with:

void initialize() {
    if (!isInitialized()) return;
    ...
}

When I read the first version, I make a note to look for an else clause while I
am reading the then clause. I mentally put the condition on a stack. All of this is
a distraction while I am reading the body of the then clause. The first two lines
of the second version simply give me a fact to note: the receiver hasn’t been
initialized.

If-then-else expresses alternative, equally important control flows. Guard
clause is appropriate for expressing a different situation, one in which one of
the control flows is more important than the other.

(via Sample chapter of Kent’s book, Implementation Patterns)

akuhn Java, Patterns, Read this!, Readability

Assert that Assertions are Enabled

March 24th, 2009

I have just been told that yet another group failed their exercises due to broken assertions. It is very important that your code makes sure that assertions are turned on! Otherwise it might contain broken assertion of which you are not aware.

Use the following code in your main class.

public class Main {
    static { assert assertionsEnabled(); }
    private static boolean assertionsEnabled() {
        try {
            assert false;
            return false;
        }
        catch(AssertionError ex) {
            return true;
        }
    }
}

And in your tests, use the following test case

public class AssertionsEnabled {
    @Test(expect=AssertionError.class)
    public void areAssertionsEnabledQuestionMark() {
        assert false;
    }
}

PS, if the code does not compile, please report, I just wrote it here in the text editor without running Eclipse.

akuhn Java, Patterns

Why Packages Anyway?

March 24th, 2009

You should use packages to structure your code. (Use of the default package is strongly discouraged.) But, what are packages?

  • First of all, packages are folders on the file system used to structure classes.
  • Each package is a name space. Class names must be unique within one package, but two different packages may contain classes with the same name. (To avoid clashes among package names, it is convection to start them with your domain name, eg ch.unibe.scglectures.p2.)
  • Packages manage visibility of classes and method. For example, while public members are visible from any package, protected members are visibile from the same package only.

Gotcha: Please beware that while folders are nested, packages are not. There is no such thing as a “subpackage”, even if folder scglectures is nested in folder unibe, package ch.unibe.scglectures is not a subpackage of ch.unibe. Thus protected members of the latter package are not visible to the former package!

Which classes belong together? It is hard to give a golden set of rules, as there are conflicting forces as work. You best follow Uncle Bob’s principles.

The first three package principles are about package cohesion, they tell us what to put inside packages:

  • The Release Reuse Equivalency Principle (REP): the granule of reuse is the granule of release.
  • The Common Closure Principle (CCP): classes that change together are packaged together.
  • The Common Reuse Principle (CRP): classes that are used together are packaged together.

The last three principles are about the couplings between packages, and talk about metrics that evaluate the package structure of a system.

  • The Acyclic Dependencies Principle (ADP): the dependency graph of packages must have no cycles.
  • The Stable Dependencies Principle (SDP): depend in the direction of stability.
  • The Stable Abstractions Principle (SAP): abstractness increases with stability.

(via Uncle Bob’s Principles of OO Design)

akuhn Java, Patterns

Java Job Trends

May 23rd, 2008

Over at manageability, there is an article about trends in java job ads. This is even more interesting than my recent google trend searches. The blog post shows many disruptive trends, for example, how both Hiberante and Spring are killing EJB.

Hibernate / Spring vs EJB

This is a good thing to happen. EJB was the most broken framework I have ever seen (and was actually the reason why I left industry and came back to academia). If you want to know how broken EJB really was, just consider that after its introduction even POJO became a buzz word. POJO stands for no less than “Plain old Java object”!

(via Manageability)

admin Java

The Good, the bad, the ugly

May 8th, 2008

The Google Singleton Detector can be used on your code base to detect things matching a classic singleton pattern and also some more subtle singleton variants which they call hingeltons, fingletons, and mingletons.

(via Pure Danger Tech)

admin Java, Patterns, Tools