Java Forum / General / February 2006
Your 2 cents: Java Generics, love it, hate it, or waiting?
Danno - 24 Jan 2006 06:33 GMT Right now I think they suck especially when working with libraries that are older than tiger. That is my opinion. What is your vote on generics?
Chris Uppal - 24 Jan 2006 09:24 GMT > What is your vote on generics? ++against;
-- chris
Roedy Green - 24 Jan 2006 18:49 GMT On Tue, 24 Jan 2006 09:24:02 -0000, "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly quoted someone who said :
>> What is your vote on generics? > >++against; The problem with it is you create 10 times as many errors as you catch because it is so complicated with such ugly syntax. The big difference is, you can catch the errors it creates at compile time.
My contribution to the solution is canned code, e.g Comparable, Comparable, HashMap that you can copy paste and insert the class names. It is just about impossible for a newbie to figure the structure out and the error messages are utterly baffling.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
hiwa - 24 Jan 2006 09:56 GMT I like only its shallowest/simplest usage. Other parts are just clumsy, as I feel them.
Timbo - 24 Jan 2006 10:01 GMT > Right now I think they suck especially when working with libraries that > are older than tiger. That is my opinion. > What is your vote on generics? I liked them at first, then I thought they were odd, but now I understand them properly I like them again. I do think some of the type inferencing is hard to follow though.
Hendrik Maryns - 24 Jan 2006 12:14 GMT Timbo schreef:
>> Right now I think they suck especially when working with libraries that >> are older than tiger. That is my opinion. [quoted text clipped - 3 lines] > understand them properly I like them again. I do think some of the type > inferencing is hard to follow though. ACK
- -- Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Ed - 24 Jan 2006 10:08 GMT Danno skrev:
> Right now I think they suck especially when working with libraries that > are older than tiger. That is my opinion. > What is your vote on generics? Well, generics are optional; so I'd have rather the question have been phrased, "Do you use them?" To which I'd have answered, "No."
I do not, however, convulse into a frothy rage when I work with code that does use them.
The use/not-use generics argument sleeps at the bottom of the lightless, freezing ocean alongside the end-of-line/new-line open-bracket argument; if you have the time and passion, you can charter a submersible to go down and snuffle around in the silt.
But it just doesn't matter.
.ed
-- www.EdmundKirwan.com - Home of The Fractal Class Composition.
Chris Smith - 24 Jan 2006 16:22 GMT > Well, generics are optional; so I'd have rather the question have been > phrased, "Do you use them?" To which I'd have answered, "No." This is simply not true. Generics are NOT optional when reading and trying to understand the Java language specification. They are NOT optional when working with third-party code. They are optional if you work on your own code in your own basement and sell it as shareware on the internet for a living.
> But it just doesn't matter. Of course it matters. If it didn't matter, why would Sun have spent probably several million dollars on providing the feature.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Ed - 25 Jan 2006 11:09 GMT Chris wrote:
"They are optional if you work on your own code in your own basement ..."
That's indeed what I meant.
And when I said, "But it just doesn't matter," I meant, "But it just doesn't matter to me," as in: this is my personal vote.
Apologies.
.ed
-- www.EdmundKirwan.com - Home of The Fractal Class Composition.
opalpa@gmail.com opalinski from opalpaweb - 24 Jan 2006 12:54 GMT My direct programming experience is they do make portions of code a little shorter to write and clearer to read.
That positive is in part negated by how confusing previously straight forward documentation has become. The solution for this is to use java 1.4 documentation and java 5.0 compiler.
Well over 90% of my generics use is in ArrayList, HashMap, HashSet, TreeSet, and my own pair class. I use these genericised classes, but have made only two genericised classes on my own: pair, and a very simple NoRemoveIterator.
I do not use generics in Comparators. Comparators are simple when used with Object instances/casts and the mental burdon of using generics in Comparators seems to outweight the benefit in my opinion, for now.
Opalinski opalpa@gmail.com http://www.geocities.com/opalpaweb/
Alan Krueger - 24 Jan 2006 12:58 GMT > Right now I think they suck especially when working with libraries that > are older than tiger. That is my opinion. > What is your vote on generics? Haven't had a chance to use them yet. We may be able to move into 2005 when most of our customers move beyond 1.4 JDKs.
Joe Attardi - 24 Jan 2006 15:58 GMT > What is your vote on generics? Personally, I am a big fan. As has been pointed out, they are optional, so in cases where they are fitting, they are a great addition to the language. While some will disagree with me on it, I prefer these new language features over having to cast everything from Object.
Chris Smith - 24 Jan 2006 16:19 GMT > Right now I think they suck especially when working with libraries that > are older than tiger. That is my opinion. > What is your vote on generics? Once vote for hate.
It was a promising idea, and I'm a strong believer in static analysis for the most part. In this case, though, the weight of the extra complexity added to the language is just not worth it.
Much of the potential benefit is killed by the type erasure idea. The harder question is whether I would have like generics without type erasure. I think the answer is yes, I would have liked them.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
opalpa@gmail.com opalinski from opalpaweb - 24 Jan 2006 16:41 GMT In my opinion no benefit is lost by "type erasure". I've yet to come across a single benefit lost.
Also there is a huge benefit gained -- compatibility with previous java releases.
Opalinski opalpa@gmail.com http://www.geocities.com/opalpaweb/
Chris Smith - 24 Jan 2006 19:59 GMT > In my opinion no benefit is lost by "type erasure". I've yet to come > across a single benefit lost. No benefit lost at all? What about the ability to write code without generating warnings? To drop the ludicrous Class<T> parameters to all sorts of generic methods? Maybe you don't think these are important benefits, but it's overstating rather a lot to disagree that any benefits are lost.
> Also there is a huge benefit gained -- compatibility with previous java > releases. Specifically, the compatibility gained is the ability to use code compiled with Java 1.5 in a pre-1.5 release. This is not an important kind of compatibility, and it appears Sun has decided not to maintain it anyway, since the class file version number was changed.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Thomas Hawtin - 24 Jan 2006 20:25 GMT > Specifically, the compatibility gained is the ability to use code > compiled with Java 1.5 in a pre-1.5 release. This is not an important > kind of compatibility, and it appears Sun has decided not to maintain it > anyway, since the class file version number was changed. It's the ability to use pre-1.5 and J2ME code with generic code. 1.4 implementations of now generic types still work, as does passing and receiving now generic types to old code. Without that there would be trouble.
OTOH, without the ability to run generic code on 1.4 and J2ME, I'd have preferred a better solution. It's a bit difficult to change that now with all the unchecked code that breaks static typing out there.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
opalpa@gmail.com opalinski from opalpaweb - 24 Jan 2006 20:44 GMT > No benefit lost at all? What about the ability to write code without > generating warnings? I don't see how this is lost. Type erasure refers to generics info being lost after compile finishes, right? Type erasure does not effect the number of generated compiler warnings.
> To drop the ludicrous Class<T> parameters to all > sorts of generic methods? Can you be more specific, please. I do not see what you are referring to. Maybe we mean very different things by "type erasure". Here is an article that uses "type erasure": http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html .
Regardless of "type erasure" or .... "type retention" the paramters, signatures, documentation of methods would not change. Can you list a handful of methods that take "Class<T>" as a paramter?
> Maybe you don't think these are important > benefits, but it's overstating rather a lot to disagree that any > benefits are lost. Now I'm guessing we mean something very different by "type erasure". The items you noted are not effected by generics type info being erased after compilation.
Opalinski opalpa@gmail.com http://www.geocities.com/opalpaweb/
Chris Smith - 24 Jan 2006 21:07 GMT > > No benefit lost at all? What about the ability to write code without > > generating warnings? > > I don't see how this is lost. Type erasure refers to generics info > being lost after compile finishes, right? Type erasure does not effect > the number of generated compiler warnings. Generics without type erasure would allow the Java virtual machine at runtime to check the correctness of casts to generic types. That would eliminate the need for the compiler to generate an unchecked cast warning at compile time.
> > To drop the ludicrous Class<T> parameters to all > > sorts of generic methods? > > Can you be more specific, please. Sure. There are 65 examples in the core Java API. Search http://java.sun.com/j2se/1.5.0/docs/api/java/lang/class-use/Class.html for the string "Class<T>". None of these parameters should be necessary. (To be fair, sometimes the actual parameter serves to disambiguate the method, and prevents the need to specify explicit type parameters; but specifying an explicit type parameter would be clearer and more consistent.)
> I do not see what you are referring to. Maybe we mean very different > things by "type erasure". No, we don't. I'm just talking about the consequences of type erasure, whereas you seem to be limiting your consideration to the definition itself. For example:
> Regardless of "type erasure" or .... "type retention" the paramters, > signatures, documentation of methods would not change. Of course it would be POSSIBLE to define methods with all the same parameters they have now. It just wouldn't be sensible. There would be better ways to do it.
> Can you list a > handful of methods that take "Class<T>" as a paramter? See above.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Roedy Green - 25 Jan 2006 01:05 GMT >No, we don't. I'm just talking about the consequences of type erasure, one of the biggies is you can't say new T( ...) in your generified <T> class. With type erasure T is just Object.
Designing a type system where that was possible would be difficult since a subclass of T does not necessarily have the same constructors available as T.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Chris Smith - 25 Jan 2006 01:24 GMT > >No, we don't. I'm just talking about the consequences of type erasure, > [quoted text clipped - 4 lines] > since a subclass of T does not necessarily have the same constructors > available as T. Yep, definitely difficult, and certainly not type-safe. What would be possible, though, is:
T obj = T.class.newInstance();
or the equivalent with Constructor. Currently, you need to pass an actual parameter of type Class<T> somewhere. Of course, since there is only one possible value of that parameter, it's really no parameter at all, but just syntax boilerplate... and worse: it exposes the use of reflection on T as part of the public API of the element.
This was one of the two problems I mentioned earlier.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Thomas Hawtin - 25 Jan 2006 16:36 GMT > actual parameter of type Class<T> somewhere. Of course, since there is > only one possible value of that parameter, it's really no parameter at > all, but just syntax boilerplate... Not entirely correct. Class<Integer> may be Integer.class, int.class or, of course, null. Normally the latter two should be checked for (not always done correctly) and throw an appropriate exception. Okay, that isn't much of an improvement...
> and worse: it exposes the use of > reflection on T as part of the public API of the element. That's probably going to be exposed by implication anyway.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
John C. Bollinger - 27 Jan 2006 02:28 GMT >> actual parameter of type Class<T> somewhere. Of course, since there >> is only one possible value of that parameter, it's really no parameter [quoted text clipped - 4 lines] > always done correctly) and throw an appropriate exception. Okay, that > isn't much of an improvement... Null, yes, but are you sure about int.class? Wait a moment....
Well, I'll be! According to Sun's compiler, int.class is assignment compatible with all of these: Class<Integer>, Class<? extends Integer>, and Class<? super Integer>, yet a runtime check shows that the two classes are unequal (as should be). And... wait... Eclipse agrees! Is this actually the specified behavior? I didn't know that.
What is the twisted justification for this miscarriage of justice, logic and good taste?
 Signature John Bollinger jobollin@indiana.edu
Chris Uppal - 27 Jan 2006 13:31 GMT > Well, I'll be! According to Sun's compiler, int.class is assignment > compatible with all of these: Class<Integer>, Class<? extends Integer>, > and Class<? super Integer>, [...] It makes my skin creep too, but it seems to be the defined behaviour.
JLS3: 15.8.2 Class Literals A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class. The type of a class literal, C.Class, where C is the name of a class, interface or array type, is Class<C>. If p is the name of a primitive type, let B be the type of an expression of type p after boxing conversion (§5.1.7). Then the type of p.class is Class<B>. The type of void.class is Class<Void>.
One rather nice side-effect is that:
List list = new ArrayList(); // or some pre-1.5 code Collections .checkedCollection(list, int.class) .add(22);
will compile, but will fail at runtime ;-)
Pretty disgusting. (But thanks for pointing it out anyway, Thomas)
-- chris
Thomas Hawtin - 27 Jan 2006 16:22 GMT > List list = new ArrayList(); // or some pre-1.5 code > Collections > .checkedCollection(list, int.class) > .add(22); > > will compile, but will fail at runtime ;-) More worryingly, it should compile lint-free using generics throughout.
> Pretty disgusting. (But thanks for pointing it out anyway, Thomas) I was going to send in a patch to stop such checked collection construction at runtime when I noticed it the other week (must have got distracted). Together with removing the lazily created zero length arrays from the serialisation format.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Thomas Hawtin - 25 Jan 2006 16:36 GMT >> No, we don't. I'm just talking about the consequences of type erasure, > > one of the biggies is you can't say new T( ...) in your generified > <T> class. With type erasure T is just Object. That is nothing to do with type erasure.
> Designing a type system where that was possible would be difficult > since a subclass of T does not necessarily have the same constructors > available as T. C++ templates manages it by being, if you like, a "syntax level" feature rather than Java's "type level" feature.
The obvious way to solve the problem with Java is to introduce an abstract factory:
interface MyFactory<PRODUCT> { PRODUCT newInstance(...); }
More work for the trivial case, but more flexible and it clearly expresses the type requirements within the type system.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Dimitri Maziuk - 25 Jan 2006 17:10 GMT Thomas Hawtin sez:
>>> No, we don't. I'm just talking about the consequences of type erasure, >> [quoted text clipped - 16 lines] > PRODUCT newInstance(...); > } How's that gonna work if PRODUCT is a T? -- it still has to call "new PRODUCT( ...)" at some point and that's still not possible without passing it a specific type (or fixing the whole constructor mess).
Dima
 Signature We're sysadmins. Sanity happens to other people. -- Chris King
Thomas Hawtin - 25 Jan 2006 17:41 GMT > Thomas Hawtin sez: >> [quoted text clipped - 6 lines] > without passing it a specific type (or fixing the whole constructor > mess). Implementations of the interface are specific to a particular type. Or they delegate in some way - constructors are not the only way of getting hold of an instance.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
opalpa@gmail.com opalinski from opalpaweb - 25 Jan 2006 18:02 GMT > Sure. There are 65 examples in the core Java API. Search > http://java.sun.com/j2se/1.5.0/docs/api/java/lang/class-use/Class.html [quoted text clipped - 3 lines] > parameters; but specifying an explicit type parameter would be clearer > and more consistent.) Wow. Thanks for the info.
Opalinski opalpa@gmail.com http://www.geocities.com/opalpaweb/
opalpa@gmail.com opalinski from opalpaweb - 24 Jan 2006 20:51 GMT > Specifically, the compatibility gained is the ability to use code > compiled with Java 1.5 in a pre-1.5 release. This is not an important > kind of compatibility, and it appears Sun has decided not to maintain it > anyway, since the class file version number was changed. I was of something else: If you have sources that were written before 5.0 you can write new classes which use generics and have data flow between instances of previously written classes and generics using classes.
--
If you have classes B,C,D which use class A internally, where class A is a container. You then modify A to be a generic, paramterizable on Classes. The change to A does not break B,C,D. B,C,D can stay excalty as they were even though the container they use internally has changed to be a generic.
Opalinski opalpa@gmail.com http://www.geocities.com/opalpaweb/
Chris Smith - 24 Jan 2006 21:17 GMT > I was of something else: If you have sources that were written before > 5.0 you can write new classes which use generics and have data flow > between instances of previously written classes and generics using > classes. It would, of course, be possible to do this without type erasure as well, in exactly that set of circumstances where it's safe, by giving an appropriate definition of raw types. When it's not safe, you could provide trivial wrappers (much like the current Collections.checkedList, except without its stupid Class<E> parameter; see earlier post) that would fit the necessary API and cast at run-time. The result would be better than what we have now.
> If you have classes B,C,D which use class A internally, where class A > is a container. You then modify A to be a generic, paramterizable on > Classes. The change to A does not break B,C,D. B,C,D can stay excalty > as they were even though the container they use internally has changed > to be a generic. Assuming the result only has to run on Java 1.5, this doesn't require type erasure. And since Java 1.5 produces a new class file version number, even the current implementation doesn't save you from that, anyway.
So you just define the raw type, as used in the old source and binary code, as being equivalent to what we now call the type erasure of the type, and voila! Everything works.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Roedy Green - 24 Jan 2006 22:39 GMT >Specifically, the compatibility gained is the ability to use code >compiled with Java 1.5 in a pre-1.5 release. This is not an important >kind of compatibility, and it appears Sun has decided not to mai There is another kind of compatiblility. The same class name can be used with and without generics.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Chris Smith - 24 Jan 2006 23:08 GMT > >Specifically, the compatibility gained is the ability to use code > >compiled with Java 1.5 in a pre-1.5 release. This is not an important > >kind of compatibility, and it appears Sun has decided not to mai > > There is another kind of compatiblility. The same class name can be > used with and without generics. Sorry, I don't understand you here.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Roedy Green - 25 Jan 2006 01:10 GMT >Sorry, I don't understand you here. The way things are, JDK 1.5 ArrayList has generics. You can call it with JDK 1.4 code, without trouble, ignoring its genericity and putting up with warnings. Without type erasure, I think you would need to use two separate classes: ArrayList (without Generics) and GArrayList (with generics)
You would be forced to use generics whenever you used GArrayList and could not use generics with old ArrayList. Somebody told me that is what happened in C# when they did their generics without type erasure.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Chris Smith - 25 Jan 2006 01:40 GMT > The way things are, JDK 1.5 ArrayList has generics. You can call it > with JDK 1.4 code, without trouble, ignoring its genericity and [quoted text clipped - 5 lines] > could not use generics with old ArrayList. Somebody told me that is > what happened in C# when they did their generics without type erasure. Ah! That is one way of doing it. Earlier, I proposed a different solution. That was to define the raw type as being the same as what is now called the type erasure of the type, but expanded as an explicit parameterized type instantiation. For example, "Map" would become "Map<Object,Object>".
This means, of course, that many of the existing uses of raw types would be incompatible with generic types. For example, a method defined to take a parameter of Map would be incompatible with Map<String,String> because there is no implicit assignment from Map<String,String> to Map<Object,Object> (which is the implicit expansion of Map). That's no insurmountable problem, though... just an inconvenient API. It can be solved in several ways:
1. As always, deprecate the old API, introduce a new overload that takes the right type (note that since we don't have type erasure, overloads can be distinguished by type parameters). Eventually, in Java 1.97 (also known as Java 97.0) remove the deprecated method.
2. In the short term, provide mappings that let someone define checked adapters between types. For example, define Collections.typedMap, which is a method of two type parameters K and V, which takes a parameter of type Map<Object,Object>, and returns a result of type Map<K,V>, and performs type checking on every mutation operation to ensure that the type safety is maintained. Similar, define a Collections.untypedMap which does the inverse (and also needs to type-check, since you can add things to a Map<Object,Object> that can't be added to a Map<K,V>).
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Oliver Wong - 27 Jan 2006 22:11 GMT <opalpa@gmail.com> wrote in message news:1138120899.841733.39100@f14g2000cwb.googlegroups.com...
> In my opinion no benefit is lost by "type erasure". I've yet to come > across a single benefit lost. It would have been nice if you could use "instanceof" with generics.
<example> public void someMethod(ArrayList<?> foo) { if (foo instanceof ArrayList<String>) { //... do something } } </example>
Similarly, it'd be nice if the runtime checked generic parameters in casts and threw the ClassCastException occasionally:
<example> ArrayList<Comparable> bar = getArrayListOfComparables(); try { ArrayList<String> foo = (ArrayList<String>)bar; } catch (ClassCastException) ( System.err.println("bar is an ArrayList, but not an ArrayList<String>"); } </example>
This would only be possible if the generic type was not erased at runtime.
- Oliver
Thomas Hawtin - 24 Jan 2006 18:51 GMT > Right now I think they suck especially when working with libraries that > are older than tiger. That is my opinion. > What is your vote on generics? Vote for.
Makes code cleaner and very much easier to understand (so long as you understand the language, of course). It's particularly important for boundaries between classes. OTOH, it isn't going to appeal to those that like dynamically typed languages.
Erasure is irrelevant the vast majority of the time.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Danno - 24 Jan 2006 19:17 GMT So, question:
For now, do you @SupressWarnings when you are using external legacy libraries on methods that you have no way of reconciling?
opalpa@gmail.com opalinski from opalpaweb - 24 Jan 2006 19:51 GMT I notice the following:
javac '-Xlint:-unchecked' x.java
is broken with the javac I'm using right this moment.
"These options are non-standard and subject to change without notice." the compiler acknowledges the flag but it doesn't respond correctly.
I don't like that the following code:
ArrayList<List> l = new ArrayList();
is to be written:
ArrayList<List> l = new ArrayList<List>();
I get all the benefits I'm seeking with the former and therefore do not use the latter.
Opalinski opalpa@gmail.com http://www.geocities.com/opalpaweb/
Mike Schilling - 21 Feb 2006 06:39 GMT > Right now I think they suck especially when working with libraries that > are older than tiger. That is my opinion. > What is your vote on generics? Warning: I can't use them in production code, because that has to work inside containers running 1.4, so this opi ion is based on reading about generics and playing with them, not extensive use.
To the extent that generics can be used without thinking about them, e.g
List<String> list; String string = list.get(0);
they're good. They make collection types self-documenting, make code more readable, and remove the need to insert casts into many common idioms.
Once you have to think about generics, though, they're ugly. For instance, suppose I'm implementing a generic List, rather than using one, and I want to allocate an array of members:
import java.util.List;
public class MikesList<E> implements List<E> { private E[] members;
public MikesList(int size) { // Note that this causes an unchecked warning members = (E[]) new Object[size]; // *
} ... }
Why in the world can't the starred line be written as
members = new E[size];
Yes, I'm aware that the type E isn't really known at runtime, and that the result would be to create an array of Object anyway, but why must the bones of the generics implementation show through this way?
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|