Fun, or rather no fun, with generics (updated)

So, I understand that the following doesn’t work, but why doesn’t it work?

interface Adapter {}

class Adaptulator<I> {
    <e, A extends I & Adapter> void add(Class extl, Class<A> intl) {
    	addAdapterFactory(new AdapterFactory(extl, intl));
    }
}

The add() method gives me a compile error, “Cannot specify any additional bound Adapter when first bound is a type parameter” (in Eclipse), or “Type parameter cannot be followed by other bounds” (in IDEA), take your pick.

Clearly you’re just Not Allowed to use the type parameter I there, before the &, and that’s that. (And before you ask, it doesn’t work if you switch ’em, because there’s no guarantee that I isn’t a concrete class.) But why not? I’ve looked through Angelika Langer’s FAQ and can’t find an answer.

Generally when some generics limitation seems arbitrary, it’s because you’ve created a situation where the type system can’t actually enforce correctness. But I don’t see what case would break what I’m trying to do here. I’d say maybe it has something to do with method dispatch after type erasure, but there’s only one add() method, so it’s not like there’s any ambiguity…

So what’s the problem?


Update: I cross-posted this to stackoverflow.com, and Bruno De Fraine pointed out that the reason multiple bounds were introduced in the first place was to control the erasure. Since I is just going to erase to Object, it doesn’t get you anything there. Unfortunately, all I wanted was the compile-time type safety, so I’ll have to come up with something else…

2 thoughts on “Fun, or rather no fun, with generics (updated)

  1. Don’t ask me how I found this post because I don’t know đŸ™‚

    The equivalent works fine in Scala
    trait Adapter[E] {}

    class Adaptulator[I] {
    def add[E, A <: I with Adapter[E]] (extl : Class[E], intl : Class[A]) {
    //…
    }
    }

    Scala has the same type erasure semantics as Java and it’s “generics” are essentially Java’s generics plus a bunch. In other words, I’d say it’s just an arbitrary limitation of Java.

  2. Good to know! I guess it helps that thinking really really hard about types was a big part of the Scala design.

    (One more reason to try to find a way to sneak Scala into my day job…)

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 )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s