Dr. Axel Rauschmayer is a freelance software engineer, blogger and educator, located in Munich, Germany. Axel is a DZone MVB and is not an employee of DZone and has posted 246 posts at DZone. You can read more from them at their website. View Full User Profile

Designing APIs With the Java 5 Language Features

10.19.2010
| 6205 views |
  • submit to reddit

While implementing a mid-sized framework, I've discovered that the following Java 5 language features can help improve the usability of APIs.

  • Generics can help avoid casts in more ways than one, especially if instances of Class are used (see my blog post on this subject).
  • Generics and constructors: Generic constructors always need a type argument, while static methods (such as factory methods) can infer type arguments from their actual (method) parameters, leading to shorter code. This is an example:
    public class Foo<X> {
    public static <X> Foo<X> create(Class<X> elementClass) {
    return new Foo<X>(elementClass);
    }
    public Foo(Class<X> elementClass) { }
    public X getElement() { return null; }
    public static void main(String[] args) {
    // Wrong type at right-hand side:
    Foo<String> foo1 = new Foo(String.class);
    // Proper way of doing it:
    Foo<String> foo2 = new Foo<String>(String.class);
    // Correctly infers the type:
    Foo<String> foo3 = Foo.create(String.class);
    }
    }
  • Interface Iterable enables the simplified for-each loops. This suggests that whenever you return an interface Iterator, you should also consider returning an interface Iterable. It is unfortunate that Java does not allow for-each to be applied to iterators. One can also use the following adapter:
    public class IterableWrapper<Elem> implements Iterable<Elem> {
    private Iterator<Elem> _iter;
    public IterableWrapper(Iterator<Elem> iter) {
    _iter = iter;
    }
    public Iterator<Elem> iterator() {
    return _iter;
    }
    }
  • Varargs are good whenever the API asks for 0 or more "things". In the past, there were often two variants of a method, one with the optional argument (be it a list or an array), the other one without it. With varargs, you can unify both ways of invocation under one signature. Additionally, many data structures can be cleanly created with varargs, for example:
    public static final <T> Set<T> makeSet(T... elements) {
    return new HashSet<T>(Arrays.asList(elements));
    }
  • Enums: Make it easy to discover the possible options for an argument. Compare this to the class SWT inside the Eclipse framework of the same name. Practically every GUI widget depends on the constants defined in this class, which makes looking up what constants apply in one particular case more difficult than it should be. Other advantages of Enums: Each enum constant is a full-blown object and one can perform all kinds of book keeping along with defining them; enums can be examined with a switch statement; the classes EnumSet and EnumMap provide memory-saving means for storing enums.
  • Interface Appendable: Unifies all objects “to which char sequences and values can be appended”. The list of implementing classes is long and includes StringWriter and StringBuffer. Consequence: Whenever you have an argument to which you want to "append" strings in a stream-like fashion, consider using this interface.

 

From http://2ality.blogspot.com/2010/10/designing-apis-with-java-5-language.html

Published at DZone with permission of Axel Rauschmayer, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Jonas Klingstedt replied on Wed, 2010/10/20 - 1:49am

The link to your blog post on generics is broken.

Joerg Wassmer replied on Wed, 2010/10/20 - 6:52am

You can also write constructors like that: public Foo(Class) Mainly useful for interdependencies between the types of multiple parameters.

Axel Rauschmayer replied on Wed, 2010/10/20 - 7:07am in response to: Jonas Klingstedt

@Jonas: Fixed, thanks.

Alexander Radzin replied on Mon, 2010/10/25 - 4:12pm

Nice digest. But you have not mentioned the concurrency package. I think it is very important thing that was introduced in Java 5.

Axel Rauschmayer replied on Mon, 2010/10/25 - 4:33pm in response to: Alexander Radzin

Oh, amen to that! But its features go much more in depth, here I wanted to list some of the new features that help on a more superficial level. These are just some of the ingredients for creating fluid interfaces.

Nils Kilden-pedersen replied on Thu, 2010/11/04 - 12:37pm

Is this a joke? Or do you mean Java 7? Java 5 was released 6 years ago.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.