Prev: Putting passwords in a properties file?
Next: Interview
From: Mike Schilling on 10 Oct 2009 13:36 Lew wrote: > Mike Schilling wrote: >> Lew wrote: >>> Roedy Green wrote: >>>> That is one of my conjectures, that type erasure was a >>>> wrong-headed >>>> idea. It weakened and complicated generics too much. Surely, it >>>> is >>>> not inherent to the notion that containers should be type safe. >>> I like type erasure. It keeps one from the temptation to use >>> genericity as an operational concept as opposed to a declarative >>> one. >> >> I almost know what this means, but every time I think I've grasped >> it, my hand seems to be empty. Could you elaborate? > > As it stands, generics provide a compile-time contract for > declarations about type relationships. In order to get run-time > behavior, i.e., operational use of type information you need to > provide a Class object; type parameters don't permit any run-time > operations. > The result is that generics provide compile-time assertions that > code > will not throw a ClassCastException or other type-related problem. > Erasure guarantees that this safety carries no run-time overhead. > > Run-time generics would sacrifice this efficiency and tempt us to > patch holes in the type analysis with procedural hacks. Instead of > analyzing the types we'd coerce them. Java still lets you do > run-time type tricks with a type token (Class object), but type > parameters are reserved for assertions about type relationships. > This forces us to deal with type problems at compile time. Got it. You don't want people codeing if (T.class.isSubclassOf(Number.class)) Is this really an issue, though? In principle you could do that with void method( Object[] o) { if (o.getClass().getComponentType() isSubclassOf(Number.class)) ... But I've never seen anything like that.
From: Peter Duniho on 10 Oct 2009 13:54 On Sat, 10 Oct 2009 00:05:37 -0700, Mike Schilling <mscottschilling(a)hotmail.com> wrote: > Erasure is needed for compatibility with the non-generic version of > the type, and that's the only reason it exists. If generics had been > present from the beginning, the type parameters would be first-class > parts of the type, just as they are for arrays. (And just as they > are in .NET, where generics were used only in newly introduced > classes.) Though, .NET illustrates that an alternative approach would have been to simply create a new, parallel group of classes supporting generics, rather than to insist that the old classes be reusable via generics. I believe you're correct with respect to the motivation for having type erasure, but it wasn't a mandatory feature by any means. Pete
From: Peter Duniho on 10 Oct 2009 13:59 On Sat, 10 Oct 2009 07:54:41 -0700, Lew <noone(a)lewscanon.com> wrote: > Roedy Green wrote: >> That is one of my conjectures, that type erasure was a wrong-headed >> idea. It weakened and complicated generics too much. Surely, it is not >> inherent to the notion that containers should be type safe. > > I like type erasure. It keeps one from the temptation to use genericity > as an operational concept as opposed to a declarative one. I agree that having removed the temptation, certain code is better for having prevented certain programmers from having written code that way. But, type erasure prevents other useful aspects of generics. One in particular is the inability to use any value types with generics. They always have to be boxed, because the underlying type is always Object. Another less-common need is to legitimately need to know the exact type, including the type parameters; just as "instanceof" should be used sparingly, so too would run-time information about a generic type, but just as there are legitimate reasons for using "instanceof", completely prohibiting access at run-time to generic type information prevents those rare legitimate uses. As usual, the question isn't so much "is this the absolute, correct way to do things", but rather "is it more important to protect one's foot from being shot, or to allow more legitimate complex behaviors at the expense of the potential for foot-shooting?" Pete
From: Thomas Pornin on 10 Oct 2009 14:54 According to Roedy Green <see_website(a)mindprod.com.invalid>: > Surely, it is not inherent to the notion that containers should be > type safe. The perceived complexity of Java-like generics for containers is inherent to the notion of trying to build type-safe containers with only static typing. That's what type erasure is about: everything occurs at compile-time. When trying to avoid runtime overhead, the compile-time behaviour becomes more complex and somewhat difficult to grasp. An extreme case is the ML family of languages (e.g. OCaml) which have no dynamic typing at all, and yet provide strong, unescapable types. A "simple", type-safe container is easy: simply let the runtime system know about the element type, and perform dynamic type checks on write access (in many situations these can be optimized away). That is exactly what happens with Java arrays. The Java designers are apparently very reluctant to extend the _language_ in ways which imply non-trivial modifications of the _virtual machine_. They really prefer it when language extensions are handled with the compiler only, possibly with some additional library code, itself written in Java with as little native code as possible. Thus, when ArrayList was invented, it was added as some library code, without needing any change to the JVM itself. And, similarly, when ArrayList had to become type-safe, this was done with generics which again are handled entirely by the compiler (all the JVM has to know is that a given Class has type parameters, but it needs not know what the compiler knew about those parameters). There is a trade-off: type-erasure generics are not as easy to use as runtime type parameters, and there are a few things that they cannot do (e.g. you cannot implement ArrayList itself without at least one warning about an unchecked conversion, unless you fool the compiler with some native code); on the other hand, porting a JVM from Java-1.4 to Java-5 is easy, at least for the part about generics: there is almost no work to do. (This trend is not absolute. E.g. java.lang.ref.WeakReference was added at some point (Java-1.2 if I remember correctly) and that one requires a fair amount of tricky support from the GC implementation.) If Sun was to design Java again now, they would probably integrate type parameters with runtime support. There would not be this irksome distinction between arrays and lists. --Thomas Pornin
From: Mike Schilling on 10 Oct 2009 15:19
Peter Duniho wrote: > On Sat, 10 Oct 2009 00:05:37 -0700, Mike Schilling > <mscottschilling(a)hotmail.com> wrote: > >> Erasure is needed for compatibility with the non-generic version of >> the type, and that's the only reason it exists. If generics had >> been >> present from the beginning, the type parameters would be >> first-class >> parts of the type, just as they are for arrays. (And just as they >> are in .NET, where generics were used only in newly introduced >> classes.) > > Though, .NET illustrates that an alternative approach would have > been > to simply create a new, parallel group of classes supporting > generics, rather than to insist that the old classes be reusable via > generics. It's technically feasible, sure, but given the amount of existing Java code when 1.5 was introduced, imagine the dumbfoundment with which a new and incompatible set of, e.g. collections classes (and, far worse, collection interfaces) would have been greeted. |