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…
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.
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…)