The Artima Developer Community
Sponsored Link

Computing Thoughts
Back to Generics: Contravariance and Erasure
by Bruce Eckel
October 14, 2005
The Concurrency chapter is finished (hurray!), and now I re-wade into the mysteries of Java Generics. The chapter isn't looking as bad as I was remembering, but there are still some issues that I'm struggling to understand and explain.


For example, someone pointed out that Bertrand Meyer had gone into depth on covariance and contravariance in his book "Object Oriented Software Construction" (I have the 2nd edition). I'm feeling reasonable about my grasp of covariance, but I was hoping that he might enlighten me about contravariance (that's the <? super Foo> notation). Alas, his conclusion is this, on page 626:

Contravariance, as a result, leads to simpler mathematical models of the inheritance-redefinition-polymorphism mechanism. For that reason a number of theoretical articles have advocated contravariance. But the argument is not very convincing, since, as we have seen and as the literature readily admits, contravariance is of essentially no practical use. ... So rather than trying to force a covariant body into a contravariant suit, we should accept the reality for what it is, covariant, and study ways to remove the unpleasant effects.

No particular gold to mine there. But it is interesting to see Meyer do a wholesale dismissal of contravariance, a feature which is built into J2SE5. And confusing -- did Meyer not want to put contravariance into Eiffel and therefore argue that it is a misfeature, or is it genuinely a misfeature in J2SE5? It's certainly not something that you use terribly often, although when you need it -- and so far I've only plugged it in on the basis of compiler complaints -- there doesn't seem to be any other solution.

In any event, I'm still waiting for an insight to explain contravariance.

My second question for this weblog entry concerns the neverending erasure issue. In the interim since the last time I was struggling with this chapter, it occurred to me that there might be another possible option instead of using erasure.

Erasure solves the problem of so-called "migration compatibility," so that generified clients can be used with non-generified libraries, and vice versa. But what if the Java standard library had been forked at this point, into a generic version and a pre-generic version? It seems to me that this might have worked, but I may not have thought about all the implications yet, and one of those implications may have prevented forking.

An argument against forking is the typical one, which I admit is usually legitimate: you've suddenly multiplied the required effort to maintain the forked libraries. But if that was really the reason that we have erasure, I would argue that the erasure solution moves the burden of effort from the producers of Java onto the consumers, where the total effort required (and productivity lost) will be much, much greater. So I'm hoping that the answer to this isn't: "yes, we could have forked the library but we didn't want to do the work, so you got erasure instead."

As an aside, C# also does a kind of erasure but it's not as severe as Java's, and the reason is because generics are not a C#-specific feature, but rather a feature that must work across .NET, which supports multiple languages. Not all of those languages support generics, so there must be a kind of partial erasure to allow for that lack of support. Too bad that they couldn't have gone the other way and said that all .NET languages needed some kind of generic support.

Talk Back!

Have an opinion? Readers have already posted 8 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Bruce Eckel adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Bruce Eckel ( provides development assistance in Python with user interfaces in Flex. He is the author of Thinking in Java (Prentice-Hall, 1998, 2nd Edition, 2000, 3rd Edition, 2003, 4th Edition, 2005), the Hands-On Java Seminar CD ROM (available on the Web site), Thinking in C++ (PH 1995; 2nd edition 2000, Volume 2 with Chuck Allison, 2003), C++ Inside & Out (Osborne/McGraw-Hill 1993), among others. He's given hundreds of presentations throughout the world, published over 150 articles in numerous magazines, was a founding member of the ANSI/ISO C++ committee and speaks regularly at conferences.

This weblog entry is Copyright © 2005 Bruce Eckel. All rights reserved.

Sponsored Links


Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use