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.
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.
I was really hoping they'd make another leap up to Java 60.
It's hard to beleive you're posting at -1
No folly is more costly than the folly of intolerant idealism. - Winston Churchill
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.
... 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)
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.
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.
I don't think there's any merit to that particular statement about backwards compatibility. Can you run you Java 5 code on a Java 2 VM? (They skipped 3, 4 and 5 right?) Generics were released with .Net 2.0. All the the .Net 1.1 code written runs on the 2.0 VM. There wasn't a whole mess of API changes that were obsoleted with the 2.0 it was ehancements to the API and bug fixes. What does forward compatibility even mean?
Uhm, can someone explain to me how NEW features of a language can be backwards compatible?
Can I create generics in Java 1.1? If not then how exactly is their generics implementation backwards compatible? Call me crazy but I'm a bit skeptical. I just don't see how this can be done in ANY language. Just because you can run multiple versions of the runtime on the same machine doesn't mean that your new code is backwards compatible.
Office 97/2000/XP/2003/2007, for example. I take it you've never used MS software.
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).
.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.
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
I guess it is time for a new application programming language.
The bat signal is sweeping the skies! Jon Katz, where are you?
Fascism trolls keeping me up every night. When I starts a preachin', he HITS ME WITH HIS REICH!
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.
.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.
On topic, C# 2.0 was introduced with
Jeremy
Unworkable. Polymorphism and ifs/switches are SEVERAL ORDERS OF MAGNITUDE faster than database access. So it's better to keep them separated.
Q uery for an example.
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_
It's compatible in that you can code something with a Java 5/Java 6 compiler, but is still runs on the Java 4 runtime. This is because they implemented generics as a language kludge rather than a true feature of the runtime. They traded performance for compatibility. Whereas with Microsoft, you can't compile something to use .NET 2.0 generics then run it on the .NET 1.1 framework.
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.
It probably gets translated into functions that run on older machines. Like C++ macros, templates and inline functions get translated into "pure" C++ code by the preprocessor, or C# 2.0 partial classes are combined together before compilation.
Just because you can run multiple versions of the runtime on the same machine doesn't mean that your new code is backwards compatible.
Uhm, how did this get modded up? Backwards compatability isn't referring to running multiple JVMs. It's referring to the fact that you can write new classes that use generic types and methods, and those classes are still byte code compatible with pre-generic classes. This is because the type checking done by generics is compile time only - typing info is removed from the final compiled class via type-erasure. Asking how something can be true is one thing, asserting it isn't when you obviously have no idea what you're talking about is trolling.
"The problem with internet quotations is that many are not genuine" -Abraham Lincoln
I think they mean the Java6 Generics code is compiled to bytecode that will run on previous versions of the JavaVM, in effect allowing you to create Generics in older Java, although I admit I haven't checked this.
No, you can't.
If your code uses Java 5 features then it won't run on JDK1.4. You can use tools like Declawer or Retroweaver to run 1.5 code on 1.4 but only to a certain degree.
Who ever saw a version of a Microsoft product that was compatible with the previous version?
.NET in a matter of (admittedly frustrating) days.
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
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.
The original post is being just a little specious on generics -- the reason Java generics are backwards compatible is that they aren't generics, they're just automatic type conversions when accessing collections. Whee. C# generics may not be up to the level of true generic programming (e.g. C++) but they are at least 'templates' in the sense that ArrayList is a different type from ArrayList.
Java has come a long way but there's still a reason Java programmers cost about 60% of the cost of actual C++ programmers (curse them).
Whence? Hence. Whither? Thither.
Simple: in the case of Java Generics, old code can still use generic collections.
So, for example, if you have some old code that adds Strings to a List, you can pass it a List of Integers from new code, and it'll happily add Strings into your generic List of Integers.
A more useful example might be something where old code promises it'll only add Strings so you can pass a generic list of Strings, only to discover at some random point later where the legacy code accidentally added a StringBuffer.
Seriously, though, you can't use generics in pre-1.5 code. Any code that uses generics generates binaries that only work in 1.5 or later JVMs. (Despite the fact that generics are compile-time only.) The only "backwards compatible" part is that pre-1.5 code will still compile and pre-1.5 binaries will still run. As I've suggested above, though, that backwards compatibility completely defeats the purpose of generics.
Which isn't to say they're completely useless, but they're essentially no more useful than a simple comment to indicate what the programmer wants the collection to contain rather than what it actually contains. Especially when legacy code is involved.
There was a time when I actually was hoping to move from Java 1 to 1.1 and then later from 1.1 to 1.2 The move from 1.2 to 1.4 was still a good thing. However after trying Java 5 and 6 I refuse to move away from 1.4 I do not feel the need to move from something that works to something that pretends that it does more than it really does and introduced an entire set of problems on the way. As far as I am concerned the language is already bloated. I would love to see Java drop inheritance off entirely (and I have used it correctly too,) but there is no need for it really. Everything can be done with interfaces and libraries. From what I see the game is not really concerned with 'correct' implementations of pure coding paradigms, but it is rather concerned with good easily maintainable solutions where the mix of developers mostly consists of below average coders. Oh, and bringing varargs into a language? Talk about shooting yourself in the foot.
You can't handle the truth.
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++.
You can compile code that uses generics and run it on older versions of the virtual machine, that is, the bytecode implementation of generics looks like regular, pre 1.5 bytecode
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.
It's compatible in that you can code something with a Java 5/Java 6 compiler, but is still runs on the Java 4 runtime.
Which happens seldom, because by default the JDK will output a classfile version that older JVMs will refuse to run. People compiling for retrograde targets usually use a JDK from that version too, otherwise they could inadvertantly target standard library API's that don't exist in older versions. Java could make non-erased generics in the future too, just by way of changing the classfile specification and just not erasing them from version 8 on (it's too late for 7). All in all it's mystifying why they did as little as possible with respect to generics, especially in the face of superior generic systems like those in Pizza, other than that they didn't want to disturb the programmers and managers that they believe, by and large, are stupid sheep and easily frightened.
I didn't know that Wadler was behind GJ. I can call GJ's erased generics a kludge, a crock, a hack, a half-assed unsound system, but Wadler really does know his shit.
Erasure isn't the complete end of soundness anyway -- scala generics are erased too, and it still has a far superior type system.
Done with slashdot, done with nerds, getting a life.
Right... but you can recompile the source telling javac to produce class files that are 1.4 compatible: `javac -target 1.4'
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!
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.
They can do this because all checking is done at compile time. No features were added to the runtime to get this.
o w")).get(2)).intValue();
Once compiled into bytecode a Vector>> looks just the same as a regular vector of objects and the compiler takes care of all the casting for you.
No more
int i = ((Integer)((Vector)((Hashtable)vec.get(3)).get("w
Just
int i = vec.get(3).get("wow").get(2);
Well, this example used the auto-boxing feature too to convert the Integer to an int.
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!
*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.
That's clever, yes. I suppose there has to be one of these in every "discussion". Thanks for increasing the signal-to-noise ratio and all that.
Web2.0: I love when people Flickr my cuil and digg my boingboing until my google is reddit and I start to yahoo
Replying to self....Should have used preview.... my <'s and >'s didn't show up right in the text.
...
It should have said
Once compiled into bytecode a Vector<Hashtable<String,Vector<Integer>>> looks just the same as a regular vector of objects and the compiler takes care of all the casting for you.
While you are mostly correct, Microsoft has been removing compatibility features in newer versions of Windows. OS/2 and POSIX subsystems present in Windows 2000 and Windows NT were removed for Vista. Actually, one of them was removed in XP SP2.
There is nothing wrong with offering compatibility. Microsoft's approach to compatibility needs to change a bit. Separating the legacy system from the modern system should be more exact like Classic support in OS X (pre intel). Really old apps ran in a sandboxed OS9 install. (non carbonized) Microsoft could even go a step farther by working on something with Virtual PC. They could provide a built in DOS/9x compatibility system with say directx 5 support. That would allow most really old stuff to run while they trim some of the fat from the current winapi.
MidnightBSD: The BSD for Everyone
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
Use Mono and it runs on other plantforms: don't whine at Microsoft stuff before learning all facts.
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.
That won't work if you use new Tiger features. It's just like you're using an older version of compiler.
You have that backward. VS is tied to a particular version of .Net, not the other way around.
And yes, that does suck.
> 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.
but meh; Microsoft controls the only real .NET platform anyhow
.Net 1.1 are replaced with something else entirely in 2.0.
.Net 2.0 not necessarily work on 1.1 - code written for 1.1 will not necessarily work for 2.0.
.Net code as being a lot like Java code, except probably not portable between VMs.
This is what makes it so utterly astounding to me that a great many of the standard libraries that Microsoft pushed on everybody for
They didn't even bother with a deprecation phase - just gone.
So not only will code compiled for
You have to manually check which version you're running and run different segments of code to do certain tasks.
That's why I think of
Mod me down and I will become more powerful than you can possibly imagine!
Yep. I was extatic when C# got generics... for a while - but pretty quickly you start runnign into their limitations (or at least the limitations of the standard ones).
.cs file.
For example, you want a class that contains a list - you get to look forward to either (a) reams of boilerplate code as you forward all the methods of the list that an outside user might need, or (b) publicizing the list and completely mucking up your class invariants.
Plus, no typedef, so get, nested> class, declarations> - twice if you need a constructor. And Using statements are not a substitute unless you write your whole project in a single
A lot of coders use subclassing instead of typedef, but that opens a new can of worms - forwarding constructors, destroying the substitutability of the class, etc.
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.
The sad part of this story was that the pursuit of a better OS was scrapped. Longhorn was more than a mere codename; it was a radically different vision than what Vista ended up as. I can only imagine the frustration at Microsoft as they had to make that decision. They lost more than WinFS in the process, that's for sure.
Beware: In C++, your friends can see your privates!
The hope that deprecated will never happen.
- - - - - - - - - - -
I am a programmer. I am paid to produce syntax not grammar. Deal with it.
OK, this finally is a comment about the book itself, and not about its subject. In my practice, it is almost impossible to get people to understand that generics do not mean "a List of Objects now becomes a List of objects of certain type". Once a person latches onto this notion (that parameterization is simply a way of indicating something similar to a collection), he is almost impossible to shift from it - I've tried explaining the declaration of the base Enum (which is Enum<E extends Enum<E>> - to get the compareTo () to work in a type-safe manner) to seasoned Java developers, only to get (without exception, or even a Throwable): "Oh, I get it, that means that Enum contains other Enum-like things!". And yet the book dives right into this concept; the first glimpse of the actual meaning of parameterization does not appear until the section 2 of chapter 3, a good one third way through. If I were to do it the right way, I'd start with <T extends Comparable<T>>, explain it thoroughly, and only then allow Collection to enter the picture. So, I would disagree with the reviewer - if you want to understand ? super Foo, this is not the book, unless you are willing to skip the first 2 chapters.
I can assure you, the best way to get rid of dragons is to have one of your own.
While Java generics may be simpler and easier to use than C++ templates, they fall far short of the feature set of C++ templates. They do not really provide "generic programming" in the same sense that C++ templates do. There is much more to generic programming than being able to have a HashMap.
That doesn't sound right to me. Can you give me some examples?
Ick, pwned by the same mistake as parent poster. I meant some, this>.
OS/400. I believe it ran system/36 code. When they switched to PowerPC, programs 'converted' to 64-bit on the fly thanks to TIMI. Hope this helps.
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.
I think that this a very twisted and silly conclusion. Just because someone wrote or developed something doesn't automaticly imply that he or she is the best person when it comes to explaining everything about it. Quite frankly I think its much more of the opposite. Developers are by definition not the best people to turn to when you wish to really learn whatever they developed. While a developer would try to approach his ideas from a technical point of view most students would be more helped when you begin slow and abstract and eventually work your way up.
Naturally I'm a bit cynical here but heck. To me this has once again nothing to do with an intersting article but simply yet another post to try and push some "interesting" book forward thus hoping that someone is going to make more money out of it.
My opinion in all this is simple. If you're interested in Generics then the best place to start learning is the Sun Java tutorial. In this case the trail about Generics would sound like a good idea to start reading.
And you know whats so good about this tutorial? Its free, its from the company which developed Java (a company which doesn't only have very good developers when it comes to Java but also has people available who are quite skilled on documenting) and you can even download it so that you can read and study even if you don't have a permanent connection to the Internet.
Totally not how it works. You can (and should) install both 1.1 and 2.0 concurrently, and the bytecode runs on the vm it was compiled for. Problems averted.
Jeremy
Some IBM mainframes such as the zSeries still run System 360 code unmodified. That is 4 decades right there.
Isn't all static type checking some kind of compile-time hack? I think you're completely misinformed about 'generics' in C++, as they are more like macros than anything else. C++ templates are nothing like a real type system which can be found in Haskell amongst others...
The interactive way to Go -- http://www.playgo.to/iwtg/en/
Sun did jump from 1.4 and 5.0 in the past. Java naming and versioning is a sad story.
Solaris?
PS, you said "Linux" when you meant "GNU/Linux". AFAIK the kernel ("Linux") takes backwards-compatibility pretty seriously... obviously that's only a small part of the puzzle, the rest is up to the various distributors.
At the end of the day, does it matter? If you have the source to the programs you run then you can always update them to work with newer systems. If not then, well, that comes with the territory.
The most far reaching changes to Java in Java 5 are the changes to improve support for concurrency. Generics are just syntactic sugar that improve compile time type checking. The concurrency support features offer fundamental improvements in the way you can structure your applications to take advantage of increasingly parallel hardware architectures.
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).
This is a great construct, but I found that it can be quite inefficent because it creates an Iterator and uses that to traverse whatever is being passed. For some collections such as ArrayLists, I found using a good old loop and .get(index) performed much faster and avoided creation of Iterators and therefore needed less garbage collection. Foreach is very neat and great in lots of places, but it should come with a small health warning for the cases where performance is critical.
My application was very heavy on traversing ArrayLists though.
-- Mike
Are you joking? I hope you're joking....
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
Microsoft doesn't work. Look at all the apps they broke with XP SP2. Look at everything that doesn't run under Vista. Heck, look at what didn't work under Win XP/2K that did under NT 4. Remember the Office 95 fiasco? Microsoft is the poster boy for incompatibility. I'd dare you to name a company that had greater incompatibilities between versions than MS.
The cesspool just got a check and balance.
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.
Heh... Now you just have to get operator overloading and type inference, and you'll be able to write
like those of us with real programming languages.If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I'm less than two weeks away from taking the Java 5 certification exam, and Generics are definitely the most difficult new concept for me to get my head wrapped around. Granted I haven't studied it nearly enough yet and haven't done any large scale projects in 1.5 (we use 1.4.2 at work), so hopefully I'll be well prepared by the time next Friday rolls around. I use the Sierra, Bates SCJP book to study and it supposedly has everything I need to know about Generics for the exam, but is it everything I need to know for the "real world"? Maybe I'll check this book out, but after the exam. Don't want to get confused with real applications of generics. :)
Reviewing just the first hour of video games.
Java generics are mildly useful. To even mention them in the same breath as C++ templates, however, is extremely misleading. C++ templates go far beyond simply providing type-safe collections.
<soapbox>Of course, both mechanisms are work-arounds for the defects in the strongly-typed language paradigm. For the right way to handle types, look at python. Python uses untyped references to refer to typed objects, and written code is far simpler.</soapbox>
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.
> PS, you said "Linux" when you meant "GNU/Linux"
Give it up, Richard, no one's listening.
> AFAIK the kernel ("Linux") takes backwards-compatibility pretty seriously
ballocks -- drivers break with every patchlevel release, sometimes because maintainers decide the functions looked nicer with different names and in a different order. It's the userland that tends to remain compatible over time.
Loose typing and Operator Overloading in Java?? Smithers, release the hounds!!!
Xenon, where's my money? -Borno
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.
Especially since the summary states: "safer way than C++ templates" (why does virtually every text about Java add some C++ bashing?).The Tao of math: The numbers you can count are not the real numbers.
The backward compatibility can be that library written in older version such as 1.4 can be used in JDK5. This sounds like forward compatible, but it's the JDK5 can work with 1.4 binaries. For example, if a third party lib take List, but if generic was in place in 1.4, they would have taken List. So, now, users can code with List and pass into the old library and it works. You may ask why bother. This is important because that list is also passed around in the new code, so checking is important.
Some people also says it's useless. To me, it's very useful. It's not 100% perfect doesn't mean it's useless. I think those people doesn't have a clue . Performance increase or not, or how it's compiled in byte code is almost irrelevent, because at least to me, it's about reuse of code in a safe way (compile time checking). Some can argue that but compile time checking doesn't work well. Sure, it's not perfect, but it works most of the time. You can always find loop whole in the language to crash your OWN code, but that's the power of the language, so you can crash your OWN code. For the sane people, generic is very helpful for a large project with many developers.
>> PS, you said "Linux" when you meant "GNU/Linux"
> Give it up, Richard, no one's listening.
Please pay attention. My reasons for making the distinction were clearly laid out in the post. When talking about the kernel vs the whole "operating system" (whatever that means) there is a clear distinction between Linux (the former) and GNU/Linux (the latter).
> > AFAIK the kernel ("Linux") takes backwards-compatibility pretty seriously
> ballocks -- drivers break with every patchlevel release, sometimes because maintainers decide
> the functions looked nicer with different names and in a different order. It's the userland
> that tends to remain compatible over time.
We are clearly talking about user-space apps. The stability of the kernel itself is not under discussion--merely the API presented to user-space programs.
The wheel is turning, but the hamster is dead.
It doesn't, but since a significant part of Java's target audience is people who don't understand/appreciate C++, it's not surprising that some of the commentary demonstrates an ignorance of the underlying models in the two languages and their relative strengths and weaknesses.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
To be fair, try finding a popular OS9 app circa 2001 that was not updated with a PPC OS X binary. A lot, probably most, of the popular OS9 apps can still be run in one form or another on an intel mac, using only included and free software. For example, Starcraft got an OS X installer at some point, and it now runs better through Rosetta than the windows version does through wine. Myst III also got an OS X update after release, and now runs on my intel Mac.
Also, Microsoft has really been prioritizing backwards compatibility too much. There is no reason for current versions of Windows to still be able to run DOS apps outside of an emulator, and it is absurd to try to pass that off as a selling point or even a nice extra feature. We would be better off if microsoft were willing to forgo some of that compatibility so that the current operating systems could be made more secure and stable, and most importantly, so that they could spend more time developing new features that would offer users a compelling reason to upgrade.
I think saying it's impossible in C++ is a bit misleading at best. C++ has had templates since the very first version of the C++ standard. As such, at least in terms of standard C++, there's simply no version that lacks templates with which to be compatible. You can't cast std::list to some unparameterized type, because there's no unparameterized list type to which to cast it -- but if you decide to create your own StringList class (or whatever you prefer to call it) it would generally be quite trivial to make it support such a cast if you wanted to (though, of course, it's probably a poor idea to create such a class).
OTOH, back before the standard, there were some class libraries that did about like Java does, and Smalltalk did before it, with a monolithic class library rooted with Object (or something similar). When compilers added templates, some of these libraries added template front-ends for the containers that worked a lot like Java generics, basically just automatically adding casting where needed. In these cases, it was pretty easy to mix the two in about the same way as Java does.
The universe is a figment of its own imagination.
If you see the error at compile time, then it's not sneaky. Feel free to use generics with Java 5. Just be sure that your work compiles ...
Take it easy? I'll take it anyway I can get it . . .
I agree completely, but understand that Microsoft is catering to business much more than Apple, and legacy applications (which often go unmodified for a decade or more) need to run on newer OSes. Otherwise businesses simply won't upgrade, and thus Microsoft looses the sale.
Apple forced the 3rd parties to release updates for OSX, and therefore all the teething problems Vista is having can be seen as a good thing... UAC means that we'll finally have 3rd party apps that work properly with unprivileged user accounts.
Jeremy
I have not done any Java in years. I wonder how this compares to duck typing as in Ruby. Can anyone explain this in terms of Ruby's duck typing and collections?
-matthew
"THERE IS NO JUSTICE, THERE IS ONLY ME." -Death
Unworkable. Polymorphism and ifs/switches are SEVERAL ORDERS OF MAGNITUDE faster than database access. So it's better to keep them separated.
CPU speed is not always the bottleneck and RAM caching blurs the distinction to some extent. Beefier servers are usually cheaper than less productive programming tools, and will get more-so over time. Further, a table lookup is often already performend anyhow. (Of course, it depends on the domain.)
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.
Perhaps, but why deviate from the relational model when much of your data is already in a RDBMS? Mixing too many paradigms requires too much translating between them, plus the mental disconnect.
(And why was I modded "offtopic"?)
Table-ized A.I.
I guess my definition of backwards compatible isn't backwards compatible with yours.
-
disable language unsupported features (generics, assertions can be compiled within a certain degree - enumerations can't) ;
-
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) ;
- ensure yourself that all of your libraries will be compatible with that VM version (not as straightforward as it sounds)
- Perform tests against the VM you're targeting, and if it's a desktop distributable application, against all VMs that came after that version
;
- ??? 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.a Duck Tape ribbon.
But just recently I ran Civilization 1 and SimTower on Vista. Both are Windows 3.1-era games. All my other games from 95/2K/XP run flawlessly on later versions of Windows.
Unworkable. Polymorphism and ifs/switches are SEVERAL ORDERS OF MAGNITUDE faster than database access.
Unless of course if you happen to have a very fast DB like, say, an "in memory DB". In-memory DBs are hot since quite some time. Oracle is on a buying spree since a few years and has bought a few companies whose sole products were "in memory DBs".
It is not uncommon nowadays to have either in memory DBs or caching technology caching amount of data so huge that, in practice, they work like an in-memory DB.
For the GP slightly on crack, try to explain to a great many Java programmer who think that Java is an OO language (the jury is still out to see if it's possible to properly do OOP in a third-generation language like Java) that set theory is the way to go. OO and set theory are two quite different beasts and I don't see much love between these two anytime soon. But, like the GP, I'm all-in for "blurring the distinction between database and app" and this is already happening in the Java world: when you've got your whole DB in memory and super-fast lookup for most of your queries ("super-fast" as in "smoking any 'traditional' DB"), you tend to start thinking that the DB "on disk" (either a relational DB or an OO DB or monkeys writing down the infos with pencils) is a detail...
Now I don't say that set-theory is bad: it is mathematically sound... While what OO really is still a matter of debate. But my point is that "more or less OO language" like Java and C# are here to stay and they don't seem to show much love for traditional DBs. In other words, the DB world is adapting to these new kids on the block, not the other way round.
Who marked this flamebait? It was answering a question about compatibility between generics and various versions of Java. Several other people made similar responses, none marked like this. WTF?
Any features included to the language, after the first release, would hardly be called as features. They just are fixes for incomplete first release. Either language designers were not aware of these already existing features (obviously, this can not be true), or, they chose not to include those features to the language.
It's been many years since I used an MS product, but my memory says that they were much better at promissing backwards compatibility than at delivering it. This may have improved.
In particular I am remembering MSAccess95/MSAccess2000, which they definitely advertised as being compatible. I ended up keeping two separate machines, one for each, with a different copy of the program on each. Changes, including data updates, were transmitted between the two as ASCII files, because if MSAccess2000 ever opened the MSAccess95 version (even when told not to save any changes) within a month the MSAccess95 version would become corrupt. The interesting thing is that it didn't happen immediately, which made it a real fun problem to trace down.
It was necessary to keep both versions running, because different clients had different versions, and they weren't about to spring for the $$$ to get a new computer just to run MSAccess2000. I never did get a straight answer about how to solve this problem out of MS, I had to figure it out myself. (Fortunately the program had been running for about a year before we bought a copy of MSAccess2000....so I had a strong hint as to where the problem lay.)
I also heard various horror stories about MSWord incompatibilities, but none of those ever affected me.
N.B.: As you can see, this all happened several years ago...around 2001. Things may well have improved. Perhaps.
I think we've pushed this "anyone can grow up to be president" thing too far.
unlike generics in C#, maintaining backwards (and forwards) compatibility with existing Java code
As a consequence of Java's attempts to maintain backwards compatibility, Java generics are nearly useless. They fail to make your code statically type-safe, and they fail to make it run faster. Yet, despite failing to achieve the two primary purposes that generics have, they still make the language considerably more complex. In contrast, using generics in C# does give you extra type safety and extra performance compared to casting.
If THIS is meant by 'backwards compatible' then someone needs to check their facts. I mean the 'unlike C#' part.
Install both versions of the runtime (or demand their presence if you have no control over deployment).
And I have yet to come across C# v1 code which doesn't compile / run in 2.0, but I'd be interested in an example.
(They skipped 3, 4 and 5 right?)
If only it were that simple. Presumably, Java 1.5 and 1.6 (also known as Java5 and Java6) are still Java 2 products. The Java 2 terminology appears to have been deprecated, however, once it became clear the Microsoft would not be pushing the Java angle anymore.
The "Java 2" term came into existence at about the time when Sun was having trouble with the Microsoft Java VM being deliberately incompatible (and in violation of contract). It appears to me that "Java 2" was the brand name Sun used to differentiate their own "real" Java from Microsoft's Java 1 VM. The "100% pure Java" effort was at about the same time.
So JVMs continued being called "Java 2" systems throughout 1.2, 1.3 and 1.4. I am not sure if it survived into 1.5 (aka 5) though. They may have discontinued it beforehand in order to avoid (further) confusion.
Java 1.5 became Java5 because Sun engineers seem completely immune to bumping major versions and the marketing people feel that "upgrade from Java 1.5 to Java 1.6" seems less compelling than "upgrade from Java 5 to Java 6".
So version-wise, Java skipped 2,3 and 4 (it went from 1.4 directly to 5.0), but system-wise(-ish) it went from 1 to 2 and then to nothing in particular since there's no pressing need to fight Microsoft on this particular battlefield anymore.
sigs are hazardous to your health
Wow, so that one datapoint completely disproves what I was saying!
Some old binaries work. That doesn't negate anything I said about developing apps to work across Win32 versions. Civ1 probably works well because it was written to use the system GUI support directly rather than doing anything funky.
I have dozens of apps that no longer work (Mechwarrior2 for Win95 is my most mourned OS-upgrade casualty)
.NET compatability concerns don't really 'matter' between versions in the same way Java does. When Java talks about compatability, they're on about old programs breaking between versions. This just doesn't happen (or has failed to happen yet) with .NET. The CLR is able to run multiple concurrent instances of the various framework versions and even supports cross-communication between the application domains using various mechanisms. Every program from 1.1 compiles fine as a 2.0 (and thus a 3.0) program, the only difference is some new base class libraries (all backwards compatible) and a few warnings about deprecated methods. Your standard Windows PC these days probably has 4 versions installed (1.0, 1.1, 2.0 and 3.0) depending on how often the user updates (.NET installers tend to ask the user to install the latest versions during setup anyway).
A lot of my clients run a heavy mixture of 1.1, 2.0 applications because there's no need to worry about compatability issues like this at the present time. If 1.1 ever suddenly disappeared, we could move to 2.0 and likely not have to change a thing. Java is too worried about maintaining IL-compatability between versions and since most people can agree there's a lot of room for improvement it's hard to see why bytecode can't be version-targetted with a translator to on-the-fly upconvert older bytecode formats when executing. That way the newer code can take advantage of generics, the older code doesnt need changing and you'll only ever have problems if you try to use a new feature on an old platform.
As I point out again Generics will work on 1.4 as long as your 1.5 compiler compiles the code to support 1.4.
Generics will also work with 1.4 / 1.5 code working together. Also 1.4 code works fine in a 1.5 JVM.
The reason being again is because it is done at the compiler level and doesn't actually add anything to bytecode in relation to Generics.
C# probably does it differently or correctly (I don't use it).
Having earlier JVMs on your machine if you have Java6 is wasteful. You just tell the compiler/eclipse to act as if the code is 1.4/1.3 and it will handle it.
C# does not produce the generic versions of code until in the last moment...bytecode translation allows that. Assemblies contain the generic version of the code, so there is no bloat, and the code runs with maximum efficiency (in the context of C#) when translated to native code.
There is an old saying that says "a programming language is not mature unless it as reached operating system status". That's what has happened to Java, which is on par with C++ in complexity.
I do not fully agree though that powerful APIs need to be complex. There are two examples that contradict this: the Qt library (very simple, yet the most powerful C++ library) and the Be Toolkit, which was very powerful as well and completely written in C++.
There was a time where the IT industry kept buzzing about how wrong C/C++'s warnings are, and how they can introduce subtle bugs etc. Now that Java has warnings, are they good?
No, the parent is completely right. I too worked on code that had quite a few ifdefs to maintain compatibility across the different versions of Windows. Actually, since it ran as a DLL in Office, it also had ifdefs for different versions of Office.
Games are different beasts: quite a few of them only read the keyboard and the mouse events and show an image on screen. They interact very little with the OS. And they usually break down in the parts that are not play-related, such as starting up, self-updating, etc.
I think Microsoft saw the binary compatibility break between 1.1 and 2.0 as a necessary evil, and I agree with them. The .NET Framework was something very new for Microsoft, and they didn't get it quite right first time. 2.0 is a marked improvement that fixed almost all of the limitations of the platform, and opened the door to easier support of a wider variety of languages such as Python and F# in addition to enabling features like generics.
However, now that 2.0 is out there, I don't think Microsoft is eager to break binary compatibility again. The 3.0 "Framework" is really just a set of new class libraries on top of 2.0, which makes the install footprint for 3.0 a lot smaller amongst other things. The CLI is pretty mature as of 2.0, so I expect that only the CLR (the class libraries) will change for the forseeable future.
1.5 and 1.6 are still the version numbers used intenally afaict. java 5 and java 6 seem to be no less marketing names than java 2 (though it is a bit strange that they never used the names java 3 and java 4 but stick to java 2 for a few versions).
note: i'm known as plugwash most places but i screwd up registering that here somehow in the past and now can't register
yes, thats what it means to me to. So how is using a new feature, generics, backwards compatible? That was my original question.
I got the answer below though - you can compile using a new compiler that supports generics and then run them using an older VM because the bytecode is compatible.
It's just a confusing statement in the review. I wish Java freaks wouldn't jump the gun anytime a person questioned the language. Relax, you still have a job.
So I decided to read the link in your sig. It's a good laugh.
.NET language. One can write udfs for SQLite in any .NET language. .NET, wtf? .NET language, right? .NET, they pay for Windows. If I run Java on Windows, am I paying mandatory upgrade fees for Java?
1) Public Domain APIs - Right, MS is gonna sue me because I called a method they didn't want me to.
2) Standard Library Source Code Availability - You can get it through Rotor, or get the source to Mono.
3) dotNet Purity Is A Myth - Yeah, JNI doesn't exist.
4) 75% Of Enterprise Software Development - Something about statistics being made up on the spot?
6) Superior Platform for Web Development - Mmm hmm. LAMJ? Right.
7) Write Stored Procedures using Java - MS SQL Server lets one write sprocs, udfs, and triggers in any
8) An Abundance of Experienced Practitioners - Noone knows how to write software for
9) Supportive Open Source Communities - No open source ever gets developed in any
11) No Lizard Brain - What the hell does this even mean?
14) No Mandatory Upgrade Fees - Noone pays for
I could go on and on. There's strengths and weaknesses to any platform, but making ridiculous shit up does nothing good for your platform-of-choice's image.
Karma: Poor (Mostly affected by lame karma-joke sigs)
Interestingly laziness often makes Haskell code less efficent because of laziness. (TCO can end up forcing evaluation which isn't needed.)
In strict languages it's basically mandatory if you want to support functional programming styles (CSP, recursion instead of looping, etc.).
HAND.
HAND.
Yeah...because I want to require people to run whichever version I compiled it with...I'm sure that's a good idea.
Totally how it works. You can (and should) write as much code as possible that'll work anywhere.
Then load the assemblies that are specific if you have to.
Mod me down and I will become more powerful than you can possibly imagine!
Please, name ONE other operating system out there that can claim to run decade-old binaries flawlessly in its most recent incarnation.
IBM's mainframe OS runs code from the '60's, methinks.
Actually, yes. You claimed there was no way the OS could run old binaries, and I disproved your claim with evidence that old binaries do run.
*sigh*
Go look up the term "polemic"
Actually, yes. You claimed there was no way the OS could run old binaries, and I disproved your claim with evidence that old binaries do run.
No.I was talking about the apps I worked on as a Win32 developer. I said that "there is NO FUCKING WAY that the OS runs the old binaries". Note the word "the" - meaning the specific apps I was talking about. I never said that the OS runs NO old binaries, just that the binaries we had didn't run without alteration between OS revisions.
If I'd meant what you claim I said, I'd have said "there is NO FUCKING WAY that the OS runs old binaries" - which I didn't say.
Which is why what you said has no relevance to my claim - which clearly, you didn't understand in the first place.
I guess my definition of troll isn't backwards compatible with yours.
Trust me, you want to avoid hours and hours of debugging, however, if you still aren't convinced, I seriously advice you to try it and get back to this forum in a couple of years. Back to the main thread, C# did great in not having those "semi-backwards" compatibility issues: all of C# 2.0 new features are incompatible with previous CLR versions. Therefore, if you want to benefit from them, you have to adopt all of the new (by then)
Instead, Sun chose to release some backwards incompatible features, and the ones who are compatible, must be turned on with compiling options (and you must remember to turn off those that aren't) ; Sun released it's next three different IDEs (Netbeans, JSC, JSE) at months separated dates, and they featured different degrees of Java 5 support ; and last but not the least, if you find
No really exciting differences, but the text without Slashdot's edits (which removed links, sub-headings and a paragraph that explained what I was doing) can be found here.
http://www.acooke.org