Skip to content
February 20, 2011 / marrowboy

Naming Things

There are only two hard things in Computer Science: cache invalidation and naming things.
— Phil Karlton

I’ll deal with cache-invalidation another time perhaps, and rather than write an overblown treatise on the correct way to name things, I’ll just go through a couple of naming-things tricks in Java which can make your life easier.

Where is typedef?

What is typedef?

Java doesn’t have a typedef keyword. It’s used in C and C++ to allow programmers to provide a pseudonym for a type. So I can say at the start of my program:

typedef float MYFLT;

Then I can declare variables of type MYFLT all over the place and they will all be floats. If I later want to recompile using double everywhere to hit a different point on the speed/precision curve, I just have to swap out a header file to inclue:

typedef double MYFLT;

And we’re golden. Thanks to cSound for that example.

Typedef in Java?

That’s nice but we can achieve that in Java by using polymorphism, so typedef is perhaps not so useful. Sometimes though, I have found myself wanting to create pseudonyms for Java types for a different reason:

Map<String, Map<String, List<String>>> fastLookups = new HashMap<String, Map<String, List<String>>>();

Phew. What I want is something like:

typedef FastLookupType HashMap<String, Map<String, List<String>>>;
FastLookupType fastLookups = new FastLookupType();

And such a thing is indeed possible in Java with an empty extension class:

public class FastLookupType extends HashMap<String, Map<String, List<String>>>{}
//...
FastLookupType fastLookups = new FastLookupType();

Don’t do this! Please. This is not what you want. FastLookupType and the HashMap are not interchangeable, because extends only works one way (ie you can’t use a HashMap where a FastLookupType is expected, even though you think they’re eqivalent), so you’re restricting your consumers. There is a very good article explaining why the pseudo-typedef antipattern is not as helpful as you think, and it ends with a suggestion for a better pattern: type inference

Type Inference

Premise: The Java compiler is smart enough to work it out for you. Conclusion: Sometimes:

Map<String, Map<String, List<String>>> fastLookups = Collections.emptyMap();

The compiler can infer the correct key and value types for you. Sweet, huh? Until you try to add something to the map and you get smacked in the face with a UnsupportedOperationException. Because the Collections.emptyXXX() methods return unmodifiable collections. I haven’t found anything in the Java core classes which does what we want here, so lets see how hard it would be to write our own type-inferring-empty-hashmap-factory method:

public static <K,V> Map<K,V> newHashMap() {
    return new HashMap<K,V>(); 
}

Easy. And we’ve got what we wanted but…

// This works
Map<String, Map<String, List<String>>> fastLookups = newHashMap();

// This doesn't (type inference only works on assignment)
fastLookups.put("thing", newHashMap());

I’d have thought the compiler might figure that one out as well, but apparently not. It is a shame to have to create little helper methods all over the place for this, so we welcome the coming in Java 7 of the Diamond Operator from Project Coin (so named because each item is a small change to the language, geddit?).

Map<String, Map<String, List<String>>> fastLookups = new HashMap<>();

Cool. Bring on Java 7. Now, my other naming-things tip.

ಠ_ಠ

If you’ve ever seen a maven warning that starts like this: [WARNING] Using platform encoding, and ends like this: build is platform dependent!, then you have at least a passing familiarity with the fact that java source code can have UTF-8 encoding. This is great for i18n, so we can write like:

System.out.println("こんにちは世界");

And our sales in Japan will skyrocket. I’ll leave this here without comment:

    private boolean ʘ‿ʘ() {return new Random().nextBoolean();}
    private static class ಠ_ಠ extends RuntimeException {}

    public void ツ  () {
        if (!   ʘ‿ʘ   ()) {
            throw new ಠ_ಠ   ();
        }
    }

ʘ‿ʘ

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: