Monday, February 22, 2010

Are Generic Methods evil?

Over the weekend I ran into an interesting design issue inside of ERRest. Java supports declaring generic methods that can perform a simple type inference:

public class NonGenericClass {
    public  T objectForKey(String key) { ... }
}

What this allows you to do is:

Person p = new NonGenericClass().objectForKey("person")

Notice that we don't have to cast to Person like you would if objectForKey returned Object. So ... is this bad form? The closest examples of Sun using type inference in the core libraries is Collections.emptyList(), which can give you a type-inferred List. The difference, though, is that this is an inherently safe operation. In the example above, that code is inherently unsafe. On the upside, your API becomes easier to use -- your users don't need to think about the cast. On the downside, you might say the API is misleading, implying that this operation is in some way typesafe when it clearly is not.

I came to a happy place with it. My decision was that if this API is impossible to make type-safe (think ResultSet.getObject(String)), and if that's fairly obvious to the user of the API, then taking advantage of type inference is OK and will just save your API users time.

One catch, by the way, is that javac appears to not like a double indirection of type inference:

public class ClassOne {
    public  T methodOne() {
        return ...;
    }
}

public class ClassTwo {
    public  T methodTwo() {
      return new ClassOne().methodOne(); // this is a compile error in javac
    }
}

For some reason, javac is not capable of returning an inferred type for a method call to a method that returns and inferred type. You have to cast to T:

public class ClassTwo {
    public  T methodTwo() {
      return (T)new ClassOne().methodOne(); // this makes javac happy
    }
}

Incidentally, the Eclipse compiler is fine with the first one and doesn't need the cast. I think this is a javac bug, personally.

9 comments:

傻眼 said...
This comment has been removed by a blog administrator.
寶堅強皓 said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
禎峰 said...
This comment has been removed by a blog administrator.
家弘 said...
This comment has been removed by a blog administrator.
EulaliaS_Bro仁豪 said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...
This comment has been removed by a blog administrator.