Slashdot Mirror


Java Generics and Collections

andrew cooke writes "Java 6 was recently released, but many programmers are still exploring the features introduced in Java 5 — probably the most significant changes in the language's twelve year history. Amongst those changes (enumerations, auto-boxing, foreach, varargs) generics was the most far-reaching, introducing generic programming in a simpler, safer way than C++ templates and, unlike generics in C#, maintaining backwards (and forwards) compatibility with existing Java code." Read on for the rest of Andrew's review. Java Generics and Collections author Maurice Naftalin, Philip Wadler pages 273 publisher O'Reilly Media, Inc. rating 9/10 reviewer Andrew Cooke ISBN 978-0-596-52775-4 summary Guide to Java generics; also includes interesting discussion of collection classes.

Given the history of Generic Java, Naftalin and Wadler's Java Generics and Collections has a distinguished pedigree. In this review I'll argue that this is a new classic.

If you're a Java programmer you've probably heard of generics, an extension to the type system that was introduced in Java 5. They give you, as a programmer, a way to write code even when you don't know exactly what classes will be used.

The obvious example is collections — the author of a List class has no idea what type of objects will be stored when the code is used.

Before generics, if you wanted to write code that handled unknown classes you had to use make use of inheritance: write the code as if it would get Objects, and then let the caller cast the result as necessary. Since casts happen at runtime any mistakes may cause a runtime error (a ClassCastException).

Generics fix this. They let you write code in which the classes are named (parameters) and the compiler can then check that the use of these class parameters is consistent in your program. So if you have a List of Foo instances you write List<Foo> and the compiler knows that when you read that list you will receive a Foo, not an Object.

I'll get to the book in a moment, but first a little history. If you know any type theory — particularly as used in functional languages like ML and Haskell — then you'll recognize my quick description above as parametric polymorphism. You'll also know that it is incredibly useful, and wonder how Java programmers could ever have managed without it.

Which explains why Philip Wadler, one of the people responsible for Haskell, was part of a team that wrote GJ (Generic Java), one of the experimental Java mutations (others included PolyJ and Pizza) that, back in the day (late 90s) helped explore how parametric polymorphism could be added to Java, and which formed the basis for the generics introduced in Java 5.

So if you want to understand generics, Wadler is your man. Which, in turn, explains why I jumped at the chance to review O'Reilly's Java Generics and Collections, by Maurice Naftalin and Philip Wadler.

This is a moderately slim book (just under 300 pages). It looks like any other O'Reilly work — the animal is an Alligator this time. It's well organized, easy to read, and has a decent index.

There's an odd discrepancy, though: Wadler is the generics Guru; this is going to be `the generics reference'; generics are sexy (in relative terms — we're talking Java here) and collections are not; the title has "Java Generics" in great big letters with "and Collections" in little tiny ones down in a corner. Yet very nearly half this book is dedicated to collections.

Generics is a great, practical read. It starts simply, introducing a range of new features in Java 5, and then builds rapidly.

If you are completely new to generics, you'll want to read slowly. Everything is here, and it's very clear and friendly, but there are not the chapters of simple, repeated examples you might find in a fatter book. Within just 30 pages you meet pretty much all of generics, including wildcards and constraints.

If that makes your head spin, don't worry. Read on. The next hundred or so pages don't introduce any new syntax, but instead discuss a wide range of related issues. The chapters on Comparisons and Bounds and Declarations contain more examples that will help clarify what generics do. And the following chapters on Evolution, Reification, and Reflection will explain exactly why.

So the first seven chapters introduce generics and then justify the implementation — any programmer that takes the time to understand this will have a very solid base in generics.

There are even some interesting ideas on how Java could have evolved differently — section 6.9 Arrays as a Deprecated Type presents a strong case for removing arrays from the language. It's a tribute to the clarity and depth of this book that the reader is able to follow detailed arguments about language design. Fascinating stuff.

The next two chapters, however, were my favorites. Effective Generics and Design Patterns give sensible, practical advice on using generics in your work, including the best explanation of <X extends Foo<X>> I've seen yet (so if you don't know what I am talking about here, read the book).

(A practical word of advice — if at all possible, use Java 6 with generics. Java 5 has a sneaky bug).

The Collections part of the book was more along O'Reilly's `Nutshell' lines: the different chapters explore different collection types in detail. I must admit that at first I skipped this — it looked like API docs re-hashed to extend the size of the book.

Then I felt bad, because I was supposed to be reviewing this book (full disclosure: if you review a book for Slashdot you get to keep it). And you know what? It turned out to be pretty interesting. I've programmed in Java for (too many) years, and I guess I've not been quite as dedicated to tracking how the library has changed as I should have been — I learned a lot.

Again, a wide range of readers are welcome. This is more than a summary of the Javadocs, ranging from thumbnail sketches of trees and hashtables to a discussion of containers intended for multi-threaded programming.

The way I see it now, this part is a bonus: the first half, on generics, makes this book one of the standards; the second half is an extra treat I'm glad I stumbled across (I guess if you're some kind of weird collection-fetishist maybe it's even worth buying the book for).

I've used generics since the first beta release of Java 5 and had experience with parametric polymorphism in functional languages before that (in other words, I can tell my co- from my contra-variance). So I guess I'm heading towards the more expert end of the spectrum and I was worried I'd find the book boring. It wasn't. After claiming to be expert I don't want to spoil things with evidence that I'm actually stupid, but reading this book cleared up a few `misunderstandings' I'd had. I wish I had read it earlier.

If you're new to generics, and you don't mind thinking, I recommend this book. If you're a Java programmer who's a bit confused by <? super Foo> then this is the book for you.

The only people who shouldn't read this are people new to Java. You need to go elsewhere first. This is not a book for complete beginners. This is a great book in the classic — practical, concise and intelligent — O'Reilly mould.

You can purchase Java Generics and Collections from amazon.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.

41 of 278 comments (clear)

  1. Generics are basically good. by Z00L00K · · Score: 4, Interesting
    But it can in some cases be tricky when you get a really complex structure of Vectors containing Vectors containing Comparables. Not that it's impossible, but it can be a challenge.

    One thing that I found in Java5 was that it lacked generics for several cases, e.g. Awt/Swing objects that were able to contain Object themselves. Not that it was a big problem, but it wouldn't have been bad to have that support there too...

    Anyway - Generics is one of the best features of added to Java lately. It really helps. How I miss it when I'm programming for J2ME...

    --
    If builders built buildings the way programmers wrote programs, then the first woodpecker would destroy civilization.
    1. Re:Generics are basically good. by twbecker · · Score: 2, Informative

      Yes it is. ArrayList is a much better choice nowadays.

      --
      "The problem with internet quotations is that many are not genuine" -Abraham Lincoln
    2. Re:Generics are basically good. by gkhan1 · · Score: 2, Interesting

      I'm sorry, but I don't know what you are smoking. Vector is entirely retrofitted to use generics, and it does it fine. And a comment like "ArrayList is a much better choice nowadays" is complete BS. They are virtually identical, with one important difference, spelled out in the documentation: "This class is roughly equivalent to Vector, except that it is unsynchronized". Meaning that if you ever plan to do anything with threads, stick with Vector. In fact, always stick with Vector. It's a better class, and there is no good reason not to do it. Vector is in no way deprecated, and it never will be.

      Second, it's not hard at all to get a Foo[] array from a Vector. Just pass a Foo[] array to the toArray() function and it will fill it. It's dead easy. If you're really lazy you don't even have to size it correctly, the class will do that for you. Just tell it what type it should be in and it will do all the work. This is literally one line of code.

    3. Re:Generics are basically good. by the_lesser_gatsby · · Score: 3, Informative

      Meaning that if you ever plan to do anything with threads, stick with Vector.

      Actually, no. Use ArrayList and synchronize access to it where needed in your code. The synchronization in Vector is a very blunt tool.

    4. Re:Generics are basically good. by curunir · · Score: 2, Informative

      Meaning that if you ever plan to do anything with threads, stick with Vector. In fact, always stick with Vector.
      The problem with this logic is that the synchronization provided by the Vector class is, at best, useless. At worst, it's a recipe for disaster.

      The Problem is that the synchronization is applied at the method level. That means there's nothing to stop invocations of different methods from both attempting to update the same data inside the vector at the same time, which can cause bugs that are almost impossible to track down.

      The GP was correct...if you need synchronization, use and array list and either declare it to be synchronized or access it within a synchronized block. The Vector and Hashtable classes really have no place in code that doesn't need to compile under ancient versions of Java.
      --
      "Don't blame me, I voted for Kodos!"
    5. Re:Generics are basically good. by Nevyn · · Score: 2, Informative

      I believe the GP was talking about this problem, with reading and writing the Vector at the same time (not writing from two threads). Which is not threadsafe.

      --
      ustr: Managed string API with ave. 44% overhead over strdup(), for 0-20B
  2. All I really wanted... by Lockejaw · · Score: 3, Interesting

    ... was a quick and dirty intro to Java generics. I've had trouble finding that on Sun's site (especially ones with good code examples), but Google returns some good results. Given the availability of free tutorials, I probably wouldn't buy the book just for that.
    That said, this sounds like a good resource on Java Collections in general (though Sun's javadocs are pretty nice themselves), as well as the other features introduced in Java 5. There also seems to be some discussion of more complex generic structures.
    I'm still a bit lukewarm about buying it, but if I were getting back into a lot of Java stuff, I probably would.

    --
    (IANAL)
  3. Java 'generics' are not real generics by Cyberax · · Score: 5, Informative

    Java generics are not real generics, then you parametrize a generic class in Java you don't really create a new type. You just attach some information for Java compiler so it can perform automatic casting and save you some typing.

    Java generics don't provide real type safety, for example, you can easily put Strings in List (that's why Collections.checkedCollection kludge was added).

    In C# (or C++), on the other hand, parameterizing a generic type creates a _new_ _type_ which guarantees type safety and allows some quite interesting tricks. For example, in C# generics can be parametrized by primitive types and structs (which don't exist in Java, anyway) so you can have List without overhead of boxing. That's impossible in Java.

    1. Re:Java 'generics' are not real generics by Cyberax · · Score: 2, Informative

      Sorry, Slashdot ate "<" and ">".

      "you can easily put Strings in List" should be "you can easily put Strings in List<Integer>".

      "so you can have List without overhead of boxing" should be "so you can have List<Integer> without overhead of boxing"

    2. Re:Java 'generics' are not real generics by Jeffrey+Baker · · Score: 3, Informative

      Sure, Java generics work at compile time instead of runtime. At runtime, you can do whatever you want. But it's still true that Java generics provide a much safer interface which prevents a wide field of bugs, and which makes code much more readable. I think it's obvious that

      l = new List();
      l.add(foo);
      Foo foo = l.get(0);

      is much safer and easier to read than

      v = new Vector();
      v.add(foo);
      Foo foo = (Foo) v.get(0);

      especially when you consider that the obvious mistake

      v = new Vector();
      v.add(bar);
      Foo foo = (Foo) v.get(0);

      throws a cast exception at runtime.

      I've read a lot of complaints that type erasure (the means by which Java generics are implemented) doesn't solve the whole problem. But there was a certain class of program that generics solved, and it has made development in Java much more productive and safe.

    3. Re:Java 'generics' are not real generics by roscivs · · Score: 4, Informative

      Java generics don't provide real type safety, for example, you can easily put Strings in List (that's why Collections.checkedCollection kludge was added).

      I've never understood this objection. This will always generate a compiler warning, and depending on your compiler settings may not even compile successfully. The only time you might turn those warnings off is when you're having to deal with non-genericized legacy code.
      --
      ~ roscivs
    4. Re:Java 'generics' are not real generics by harves · · Score: 2, Interesting

      What compiler are you using??

      harvey@clownfish:~$ cat test.java
      import java.util.*;

      public class test
      {
            public test()
                {
                      List s = new ArrayList<Integer>();
                      List l = s;
                      l.add("foo");
                }
      }
      harvey@clownfish:~$ javac test.java
      Note: test.java uses unchecked or unsafe operations.
      Note: Recompile with -Xlint:unchecked for details.
      harvey@clownfish:~$ javac -Xlint:unchecked test.java
      test.java:9: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
                      l.add("foo");
                                ^
      1 warning

    5. Re:Java 'generics' are not real generics by 0xABADC0DA · · Score: 4, Interesting

      What you are missing is that it's a *good* thing that Java generics are not "real" generics.

      With "real" generics the system has two choices: either generate lots of bloated specific instances of the code, or add type-checking at runtime. CLR designers thought they were going to do the former and it was going to be 'uber leet' and fast, but found out it's not practical (most of the optimizations that C++ uses to limit bloat do not apply well in a dynamic language) so they got stuck with the latter, for objects.

      In Java, the code goes to add something to a generic list for example and it does one cast to the generic parameter type. Many times it can completely remove this check since it already knows from flow that the type is compatible. CLR can do this too, but only if it *also* knows the specific instance of the list (what the generic parameter types are), so it can remove fewer checks. This makes optimization harder as well since each use of a generic parameter can potentially block inlining and/or hoisting.

      On top of that, the tests CLR has to do are *much* slower since they have to check many parallel type hierarchies (one per generic type references). For example, when passing a LinkedList of Integers to a parameter of type List of Numbers CLR has to in effect check both List assignable from LinkedList and Number assignable from Integer.

      So in the vast majority of code not only do you end up with more checks but slower ones, and CLR has to maintain a complicated hierarchy of instantiated types to optimize this. All so primitives can be used faster in some cases, which is pretty ironic since in my experience these cases are usually easy to optimize by hand to use an array or patch out to inline C++ or JNI'd code.

      In other words they messed up their runtime for bullet points without considering the implications. Not even to mention that in Java if you don't like generics, you just don't use them.

    6. Re:Java 'generics' are not real generics by novitk · · Score: 2, Interesting

      +5?

      CLR can do this too, but only if it *also* knows the specific instance of the list (what the generic parameter types are), so it can remove fewer checks. This makes optimization harder as well since each use of a generic parameter can potentially block inlining and/or hoisting.

      There is no "only if" here, as you seem to imply. If a generic is compatible with passed parameters the CLR would remove the check in JIT in all cases just like JVM. CLR is also capable of removing the check on upcast calls (i.e. list.get()) as .NET generics are truly type-safe. Java has no ability to do this.

      On top of that, the tests CLR has to do are *much* slower since they have to check many parallel type hierarchies (one per generic type references). For example, when passing a LinkedList of Integers to a parameter of type List of Numbers CLR has to in effect check both List assignable from LinkedList and Number assignable from Integer.

      I'm not sure I understand. Implementing IEnumerable in generics doesn't imply any "parallel type hierarchies". Are you sure you are not confusing C++ templates and CLR generics?

      So in the vast majority of code not only do you end up with more checks but slower ones, and CLR has to maintain a complicated hierarchy of instantiated types to optimize this.

      Are you talking about the speed of JIT phase? This is O(1) step, who the hell cares. In run-time performance the CLR generics are a lot better than JVM ones even on reference-based collections (due to beforementioned upcast elimination). On value-based ones it's an order of magnitude difference.

      All so primitives can be used faster in some cases, which is pretty ironic since in my experience these cases are usually easy to optimize by hand to use an array or patch out to inline C++ or JNI'd code.

      This is only because Java is limited in a number of available primitives. CLR has a built-in support for extensible value-based types, so supporting them in generics without boxing is quite useful.

    7. Re:Java 'generics' are not real generics by Taagehornet · · Score: 2, Interesting

      What you are missing is that it's a *good* thing that Java generics are not "real" generics.

      It appears that you're confusing CLI generics and C++ templates. I must admit that I have little knowledge of C++ templates, but a comparison of Java's Generics by Type Erasure and C#/CLI's true generics definitely favours the latter.

      The following set of slides by Peter Sestoft sums up the differences pretty well: http://www.itu.dk/courses/PFOO/F2006/diku-javacsha rpgenerics.pdf

      Slide no. 23 sums up the major advantages of the C#/CLI implementation:

      In C#, a type parameter can be used almost as an ordinary type:

      class C<T> {
      void M(Object o) {
      T[] arr = new T[10]; // Array creation
      if (o is T) { // Instance-of test
      T t = (T)o; // Type cast
      ...
      }
      T d = default(T): // Get default value for T
      Type ty = typeof(T); // Get type object (reflection)
      }
      void MO(T x) { ... } // Overloading on type parameters
      void MO(IMyList<T> x) { ... } // and type instances
      }

      Java simply does not allow this (slide no. 32):

      [...] in Java, a generic type parameter in many respect cannot be used as an ordinary type:

      class C<T> {
      void m(object o) {
      T[] arr = new T[10]; // Declaration OK, array creation not
      if (o instanceof T) { // No instance-of test
      T t = (T)o; // Type casts are "unchecked"
      ...
      }
      Class ty = T.class; // No getting the type object
      }
      void mo(T x) { ... } // No overloading on type parameters
      void mo(MyList<T> x) { ... } // and type instances
      }

      Then of course there's the fact that C# type arguments can be value types, not only reference types. No boxing or unboxing is needed for value type arguments; hence better performance and less memory usage.

  4. Too bad Java generics are completely useless by Anonymous Coward · · Score: 2, Informative

    Amongst those changes (enumerations, auto-boxing, foreach, varargs) generics was the most far-reaching, introducing generic programming in a simpler, safer way than C++ templates and, unlike generics in C#, maintaining backwards (and forwards) compatibility with existing Java code.

    Yeah, and by maintaining that backwards compatibility, they became totally worthless.

    The only thing it offers is some compile-time sanity checking, but even that can be disabled through use of a new compiler pragma directive to suppress warnings. In fact, in several cases, you HAVE to disable warnings because certain operations (like creating an array of a generic type) are impossible without a warning.

    Ever wondered why the collection classes require you to pass in an array to the toArray(T[]) method? Because Java generics throw away the class information after compile time (although there's no reason they need to do this, they could have kept it and maintained backwards compatibility), so you have to pass in an array to give the type information Java removed.

    Java generics could have been useful, but since casting them into a non-generic type generates an ignorable warning, they become worthless. It's only a few lines of code to place a Double into an Integer collection, thereby removing then entire point completely.

    1. Re:Too bad Java generics are completely useless by LarsWestergren · · Score: 4, Insightful

      The only thing it offers is some compile-time sanity checking, but even that can be disabled through use of a new compiler pragma directive to suppress warnings.

      Many operations are ERRORS, not warnings. This is caught by IDEs, and by the compiler.

      In order to make it possible to interact with legacy code, you can pass a generified collection to a method that expects a "raw" collection. This gives you a very clear warning. So for 95% of all use cases, generics give you a lot of assistance. You manage to come up with a remaining 5% example, where a programmer casts, suppresses compiler warnings, and then passes in a object of the wrong type, and this makes generics worthless?

      Wadler was involved with the design of Haskell, and he and people like Gilad Bracha designed Java generics. I trust their skills more than a Slashdot Anonymous Coward.

      --

      Being bitter is drinking poison and hoping someone else will die

    2. Re:Too bad Java generics are completely useless by DavidYaw · · Score: 2, Insightful

      Ever wondered why the collection classes require you to pass in an array to the toArray(T[]) method? Because Java generics throw away the class information after compile time (although there's no reason they need to do this, they could have kept it and maintained backwards compatibility), so you have to pass in an array to give the type information Java removed.


      A) Before generics were added, the toArray(T[]) function already existed as toArray(Object[]). Since this function pre-dates generics, the fact that it takes an array parameter, by definition, cannot have anything to do with generics.

      B) For the interface Collection<E>, the function is defined as toArray(T[]), not toArray(E[]). The generic type T is defined locally for this function, and it does not have to be the same as type E.

      I believe that in the quote, you are suggesting that this function should be implemented as taking no parameters and returning an array of the same type as the enumerated type. While I agree that this would be useful, it does not give as much functionality as toArray(T[]), and is not a suitable replacement.
  5. Reading Generified Code Makes My Brain Hurt by MCTFB · · Score: 2, Interesting

    I don't use any of the generic syntax at all in my code as I feel it makes it virtually unreadable to other developers. The syntax is just absolutely horrible, plus as most adept Java programmers know (been coding in Java myself since 1.0), the way generics is implemented in Java is broken (depending on your point of view on this matter).

    Then there is the Collections API itself which upon first glance seems like it was written by amateurs who have never had to write any performance critical code in their lives. For this reason as well, I generally try and avoid using anything in java.util as well.

    And now they are talking about adding closures (more bloat) to Java which as I understand the proposal will be implemented under the hood in basically the same way as inner classes (another feature that is a maintenance nightmare that gets abused by novice developers ad infinitum).

    Is Java not bloated enough? Do the guys at SUN have such feature envy of C# (the bastard child of Java), that they can't just say enough is enough?

    I feel like this is all coming full circle with C++ in the sense that Java now has so many language features that it is becoming too complicated for entry-level developers to be truly productive with and now a new language is needed that has the best features of Java, minus all the bloat that totally overwhelms the initiates.

    With more features, generally comes more power, but with more power there is more room for abuse for those who don't have the wisdom to use it (i.e. newbies). Everyone in programming starts off as a newbie and needs to get their feet wet, but once you make a programming language where everyone has a light saber, but does not have the Jedi training or wisdom to use it, well then you are going to have a lot of people causing a whole lot of trouble.

    One of the main reasons why Windows software development has slowed to a crawl (besides of course the cannibalizing nature of MS on the Windows platform), is that it takes a good 4 years or more of full-time experience with the Windows API's just to become adept at programming on that platform, on top of being decent at C/C++ itself. I know Microsoft has tried to reduce that learning curve with C# and .NET, but nevertheless the learning curve is still huge. With Java, the same thing is happening. What was once a simple, yet powerful programming language has evolved into a monster on par with the same kind of crap that comes out of Redmond that is overengineered and the last thing from elegant.

    I guess it is time for a new application programming language.

    1. Re:Reading Generified Code Makes My Brain Hurt by Cyberax · · Score: 3, Insightful

      Bullshit.

      Generics syntax is quite readable and easy-to-use, especially with good IDE support. And generics certainly make the code more readable because the add type information.

      Foreach loops, varargs and autoboxing is just a minor syntax sugar, nothing really big.

      I've used a lot of collection frameworks in a lot of languages (and even wrote my very own vector and string for C++), Java Collections Framework is quite OK. It's not hard and reasonably fast.

    2. Re:Reading Generified Code Makes My Brain Hurt by LarsWestergren · · Score: 2, Informative

      Do the guys at SUN have such feature envy of C# (the bastard child of Java), that they can't just say enough is enough?

      Sun does not control the development of Java, the Java Community Process does. And it is not C# that is seen as a threat I believe, but Ruby and functional languages. There is a VERY heated debate in the Java community over the new language features that are proposed for the Java platform, and both sides put up some very convincing arguments (simplicity is good vs a language needs to evolve, for instance). See for instance the different Closures proposals...

      --

      Being bitter is drinking poison and hoping someone else will die

    3. Re:Reading Generified Code Makes My Brain Hurt by bckrispi · · Score: 2, Interesting

      Then there is the Collections API itself which upon first glance seems like it was written by amateurs who have never had to write any performance critical code in their lives. For this reason as well, I generally try and avoid using anything in java.util as well.
      And you can justify to your boss spending weeks implementing your own collections framework to save a whopping 50 ms of processing per day? To say nothing of the ramp-up time required of the poor schmuck who has to maintain code that uses your wonderful non-standard libraries.


      Seriously, I've been using the Collections framework since it was beta, and have never had a situation where its performance wasn't "good enough". Is it really "that bad" for your business need? Or are you committing the cardinal sin of premature optimization???

      --
      Xenon, where's my money? -Borno
  6. Re:C# compatibility? duh... by JebusIsLord · · Score: 4, Insightful

    Man, that is just not fair. Microsoft has been burdened with backwards compatibility like no other company out there. I mean, except on 64-bit Vista, you can still run 16-bit DOS apps in the latest release of Windows, 20+ years later! Try running a circa 2001 OS9 app on a new Mac, and let me know how that goes for you. Microsoft has been hamstrung by their commitment to backwards compatibility; I am convinced that (and bad management) are the reasons for Vista's mediocrity. Yeah, some stuff broke, but I wish they'd broken more in the pursuit of a "good" OS.

    On topic, C# 2.0 was introduced with .NET 2.0, which included bytecode optimizations that aren't backwards-compatible. The generics stuff probably could have been, but meh; Microsoft controls the only real .NET platform anyhow. Its not like they had to remain compatible with mobile phones and such, like Sun did.

    --
    Jeremy
  7. Re:All Roads Lead to Rome by Cyberax · · Score: 2, Informative

    Unworkable. Polymorphism and ifs/switches are SEVERAL ORDERS OF MAGNITUDE faster than database access. So it's better to keep them separated.

    As for metaprogramming - you can look at Nemerle (http://nemerle.org/Main_Page) which excels at metaprogramming. It's one of the best languages I've seen.

    But there's research in bridging the gap between databases and code - see http://en.wikipedia.org/wiki/Language_Integrated_Q uery for an example.

  8. Re:C# compatibility? duh... by drooling-dog · · Score: 3, Informative

    Uhm, can someone explain to me how NEW features of a language can be backwards compatible? Ummm... I think it means that programs that were written with previous versions of the language will not be broken by the new version and will continue to run correctly. That's what "backward compatible" has always meant, at least in my lifetime...
  9. Re:C# compatibility? duh... by alyawn · · Score: 4, Informative

    The language feature of generics *is* new. The compiler can still compile Java 1.1 source and can even compile to older class file versions. The generics implementation is for compile-time type checking, not runtime type checking. The compiled class file has no knowledge of generics.

  10. Re:C# compatibility? duh... by Hikaru79 · · Score: 5, Insightful

    Who ever saw a version of a Microsoft product that was compatible with the previous version?

    Are you joking? I hope you're joking. Because the alternative is that you are being criminally thick. I really think Slashdot should have a mod option -1 Misinformed

    Say what you will about Microsoft, but backwards compatibility has always been one of their cornerstones. Their compatiblity layers still allow you to run apps from the early 90's on a modern copy of Vista today. I have managed to get some very old VB3 code working with a minimum of modification on VB6, which then, using Project Analyzer, got compiling in .NET in a matter of (admittedly frustrating) days.

    And who are you comparing them with? Linux? You must be joking. Linux has trouble (read: is completely unable to) maintain binary compatibility with even relatively recent "old" code because of changing libc versions, etc.

    Please, name ONE other operating system out there that can claim to run decade-old binaries flawlessly in its most recent incarnation.

    Disclaimer: I'm a dedicated FOSS user and not a Microsoft shill in any way. But please, let's give credit where credit is due.

  11. Re:C# compatibility? duh... by Cyberax · · Score: 2, Interesting

    It means that you can create List and pass it to a legacy method which takes only unparameterized List. Or you can get unparameterized List and cast it to parameterized type.

    It's impossible to do in C#/C++.

  12. Re:C# compatibility? duh... by CastrTroy · · Score: 2

    I like the way MS implemented their Geneics. Too bad they tie the .Net framework to specific versions of VS.Net. So those of us stuck using VS.Net 2002 don't get to use .Net 2.0. And no, Generics aren't worth the cost of the upgrade.

    --

    Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
  13. Two words: Type erasure by BitwizeGHC · · Score: 4, Informative

    Java generics are kept back-compatible with the old VM spec by way of type erasure: parametric information is "erased" from the type when it is compiled. So List and List and List all compile down to the same type: List.

    Among other hiccups this makes it impossible to overload methods whose argument types differ only in the parametric information included with them.

    By contrast, C++ templates and C# generics create a type disjoint from all other types in the same type class for each set of parameters in the type declaration.

    Yet another sterling example of Java lossage.

    --
    N4st0r, trixx0r h0bb1tz0rz! Th3y st0l3 0ur pr3c10uzz!
  14. Java-only programmers? by mr_mischief · · Score: 2, Insightful

    Wouldn't someone have to be used to _only_ Java to not be familiar with at least some of these concepts?

    Enumerations are available in Pascal and pretty much all of its descendants IIRC. It's also a type of field in an SQL database for much the same purpose as enumerations in programming languages.

    The foreach loop has been in Perl since 2.0 in 1988. C# got foreach in 2000. It's in PHP. It comes from earlier FOR..IN loops from shells.

    I'm sure there are examples of the other features which are similar to the Java version of them. The syntax may be different, and the exact details of darker semantic corners may be different. The concepts, however, are pretty easy to have run across unless someone has only used the one language.

    The review seems to imply that bringing in what has been proven to work well in other languages is too confusing and should be done at a slower pace. The truth is, people program in a subset of any general-purpose language at first, and that subset grows over time. If someone works with code from other programmers, one picks up the parts of the language to which they are exposed as they are exposed to them. No one needs to cram all night to be up on all the new features of a language the day after the manual gets updated.

  15. Two words: Bracket erasure by BitwizeGHC · · Score: 4, Informative

    Sentence in the above post should have read as follows:

    So List<String> and List<java.math.BigInteger> and List<javax.swing.JComponent> all compile down to the same type: List.

    --
    N4st0r, trixx0r h0bb1tz0rz! Th3y st0l3 0ur pr3c10uzz!
  16. warning: nitpicks ahead by PhrostyMcByte · · Score: 2, Informative

    introducing generic programming in a simpler, safer way than C++ templates and, unlike generics in C#, maintaining backwards (and forwards) compatibility with existing Java code."

    *prepares to be modded troll*

    People need to stop comparing Java/C# generics to C++ templates - they take similar syntax, but they aren't the same thing. I'm not sure how one can even be safer than the other.

    And C# 2.0 maintained compatibility with existing C# 1.0 code (you still have access to the old containers) while actually giving significant performance benefits where Java is only syntax sugar that still produces the same old slow code.

  17. Java One session by LarsWestergren · · Score: 5, Informative

    Naftalin and Wadler are also holding a Java One session this year, it is on Wednesday, session id is TS-2890. If you have a Sun Developer Connection account (free) you can watch it online after the conference is over.

    I agree with reviewer, the book is very good. It is true that Java generics is a compile time check, and that the generics information is removed (erasure). Nevertheless, that was a deliberate tradeoff for backwards compatibility, and it still makes coding complex Java a lot safer and easier. Look for instance at the 1.5 and 1.6 improvements to the concurrency libraries with Future, Callable and Executors.

    --

    Being bitter is drinking poison and hoping someone else will die

  18. Re:C# compatibility? duh... by _xeno_ · · Score: 2, Informative

    As soon as you use a generic, the Java compiler requires -source 1.5 and -source 1.5 requires -target 1.5 or higher. So -target 1.4 won't work, even though theoretically generics needn't require 1.5 binaries as all the checking is done at compile-time.

    --
    You are in a maze of twisty little relative jumps, all alike.
  19. Re:C# compatibility? duh... by forgotten_my_nick · · Score: 3, Informative

    > If your code uses Java 5 features then it won't run on JDK1.4.

    Your wrong. Or at least when it comes to Generics (I haven't tested the rest). Everything is done at the compiler level. So even if you use Generics the code is changed to work in 1.4 if you set javac -target 1.4.

  20. Re:C# compatibility? duh... by RetroGeek · · Score: 2

    What does forward compatibility even mean?

    The hope that deprecated will never happen.
    --

    - - - - - - - - - - -
    I am a programmer. I am paid to produce syntax not grammar. Deal with it.
  21. Re:C# compatibility? duh... by ClosedSource · · Score: 2, Interesting

    To be fair, this is a trade-off. Generics in Java allow backward compatibility which you pay for with type erasure (i.e. generics provide compile-time autocasting so the JVM still thinks everything is an object).

    If you're maintaining an existing Java application, it's not likely that you're going to rewrite it in C# anyway. If you are starting from scratch without any commitment, I think C#'s approach to generics is better (I'm just talking about this particular issue, I'm not saying that C# is better than Java for all new projects).

  22. Re:C# compatibility? duh... by Anonymous+Brave+Guy · · Score: 2, Insightful

    It means that you can create List and pass it to a legacy method which takes only unparameterized List.

    Whether that is a useful compatibility mechanism or a fundamental weakness in the type system that defeats the entire point of generics is left as an exercise to the reader.

    --
    If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
  23. Re:C# compatibility? duh... by kaffiene · · Score: 4, Informative

    Utter BS. I worked for a couple of years developing Win32 apps. We supported everything from 95 through to XP and I can assure you that there is NO FUCKING WAY that the OS runs the old binaries flawlessly!

    The code is riddled with conditional paths for different OS versions. Testing across windows versions was a nightmare.

    I suggest it's you who is being criminally thick.

  24. Re:C# compatibility? duh... by Pipelino · · Score: 2, Informative
    No, YOU are wrong: target indicates that the bytecode will be compatible with the specified VM. In fact, there are many steps that have to be taken if you want to compile code that will run for a previous VM with a modern version of a Java compiler:
    1. disable language unsupported features (generics, assertions can be compiled within a certain degree - enumerations can't) ;
    2. compile against the libraries version of the target VM, otherwise even if the class files remain compatible, there may be calls to non-existent methods) ;
    3. ensure yourself that all of your libraries will be compatible with that VM version (not as straightforward as it sounds)
    4. Perform tests against the VM you're targeting, and if it's a desktop distributable application, against all VMs that came after that version ;
    5. ??? I forgot.
    In fact, in most projects that target an obsolete VM, it's much, much easier to get yourself the compiler for that VM, and code only on it. As an example, I'm currently running Eclipse on Java 6 VM, but since most work is still done on Java 1.4, or even 1.3, I keep most of those JDKs on my hard-drive..... In fact, I think this is one of the main reasons many people still code on Java 1.4 (as opposed to a MS pure environment, where most C# 1.2 projects translated into C# 2.0 when it appeared 2 years ago), even if it's really hard to imagine otherwise.... Sun could really have done a lot more to encourage Java development.