Feb 24

We all know how to use enums – Ordinal values and even their textual names are now accessible. Heck, we can even iterate over all of them, eliminating the need of the old-fashioned C++ “START” and “END” values.

Enums are much more though. Java implements enums as full-fledged classes:

  • They have constructors, they have methods and they have fields.
  • They are treated specially in switch statements to make them more efficient.
  • They have special classes that allows enums to be used as bit-flags, and to be used efficiently when mapping values.

Enums as Classes

When you write a new enum, you are actually creating a class containing static instances of itself – The enum values. The class will extend the class Enum (discussed earlier for its weird generification), and every instance will be initialised with a String – the name of the enum value – and an integer – the enum’s ordinal value.
So, for example, the following enum:
Continue reading »

Share
Feb 11

I’ve read Egypt Java Experts’ post about generics tips and even though I agree with the author’s claim that the generics feature make for a better API design, sometimes it’s just an overkill for the framework you’re designing.

I will take hplusplus’ example AbstractProtocolFactory and HttpProtocolFactory and hope s/he won’t mind. These classes were declared as:


public abstract class AbstractProtocolFactory<P extends Protocol,
   C extends Configuration> { ... } 

public class HttpProtocolFactory extends
   AbstractProtocolFactory<HttpProtocol, HttpConfiguration> { ... }

Part of designing a good API, especially when talking about protocols and configurations, is to make it highly configurable in a post-deployment state. This is often done by using the Strategy design pattern, and can be seen in Java’s API in several occassions.

For example, if I used message digests, I would use create a MessageDigest instance using MessageDigest.getInstance(String), making sure that the String passed is retrieved from a configuration file, so I could change the digest type later.

Going back to hplusplus’ example, I couldn’t use such a thing. This is because the factory itself is generified, and in order to use it I need to provide the class types I require hard-coded. This might prove to be type-safer than using a string, but as I said before, some things need to be changed in a post-deployment state. If a year later I would decide to change the protocol type to an XML protocol instead of an HTTP protocol, I couldn’t without redeploying my application.

Another minor twist: In the example, hplusplus defines Protocol as:


public interface Protocol<C extends Configuration>

So a Protocol is defined to be used only with a certain type of Configuration. Because of this, the AbstractProtocolFactory could accidently be told to create a Protocol with a wrong type of Configuration, like HttpProtocol with XmlConfiguration. I would make a slight change like this:


public abstract class AbstractProtocolFactory<P extends Protocol<C>,
  C extends Configuration> { ... }

That way, it’s type-safeer.

Share
Feb 10

I will start this post talking about StringBuffer and StringBuilder. As some might know, Java 5.0 added the new StringBuilder class with the same interface as StringBuffer‘s.

I can only rant about the name choice: If Sun really wanted the StringBuilder to only serve as an unsynchornized version of StringBuilder, maybe they should have used the same pattern they had with synchronized collections and maps, with a method like StringBuffer.unsynchronized(StringBuffer) or something similar, much like Collections.synchronizedList(List). These two classes don’t even implement the same interface. It seems like the only reason for this weird naming is to make it easier to find for people who’ve seen the same class in dotNet. But maybe that’s just my feeling.

Okay, enough rant. While looking at the classes, I noticed they implement Appendable, which provides methods such as Appendable Appendable.append(char). However, StringBuffer provides a method StringBuffer StringBuffer.append(char), and has no other method returning Appendable.

Now, maybe I’m just finding out something very old here, but I made a small test and wrote the following:


public interface a {
  a doSomething();
}

public class b implements a {
  b doSomething();
}

Not being able to become surprised by now, it compiled successfully. A short look using javap revealed:


l~/test $ javap code.a
Compiled from "a.java"
public interface code.a{
    public abstract code.a doSomething();
}

l~/test $ javap code.b
Compiled from "b.java"
public class code.b extends java.lang.Object implements code.a{
    public code.b();
    public code.b doSomething();
    public code.a doSomething();
}

Apparently, the bytecode contains an overload which differentiates by return value only! Obviously, doing such a thing manually would cause a compilation error. I wonder how far back this feature went? I think it’s new.. But don’t have the time to start searching for something written about it.

Share