So I just need to vent about Java 5 for the moment. If you don't feel like reading about another Python programmer bitching about Java, then just skip this entry.
I finally finished the solution for the class I am a TA for. It's a client/server chat room system that uses slash commands. It has only two threads on either the server or the client, skewing towards just polling the sockets for data and dealing with the data as it comes in than to spawn a ton of worker threads.
Simple, and yet still a pain in the ass. This was my first Java 5 app. Plus it has been nine months since my last Java app (using ANTLR in my compiler implementation language at Cal Poly SLO). So I am not approaching this from a seasoned Java coder (although I have written tons of Java code over the years for various courses). This one was 698 lines total according to sloccount, although it sure felt like a lot more.
Anyway, here are some general good/bad things about the langauge that I came across, some version 5 specific, others long standing gripes.
Good: generics. These days C is the only statically typed language that I use. Luckily since it is weakly typed, casting tends not to be a big thing. But Java is strongly typed, which means lots of casting before Java 5. But with the introduction of generics, the amount of casting out of HashMaps or ArrayLists has disappeared, thank god. That was always a pain.
Although generics do make it hard to read sometimes the method signatures of methods. There was a couple of times when I couldn't figure out how to get a method signature to work and had to just move on in the interest of time.
Bad: impure OO. Java was originally touted as this great OO language and how wonderful it was to have everything be an object. And then they tossed in primitives. I don't care that autoboxing exists in Java 5 if I can't treat an array of Strings like an ArrayList when I want to. You would think they would stop using arrays and make everything ArrayLists for convenience and to help alleviate autoboxing issues. But no! Ugh, if you want immutable arrays, why not introduce a subclass of ArrayList that does that and phase out primitive arrays? Generics give you the type safety you want along with the methods you need.
Bad: I/O. Bloody hell, when are they going to augment the docs for the various I/O classes so that it is easier to figure out what combinations of classes you want to get your desired result. Having to jump around based on who inherits or accepts what is a real crappy way to figure this all out. Is having a basic class with reasonable defaults so unreasonable?
And why can't DataOutputStream read in each thing sent over the wire individually? Can't I make a readUTF() call to read the String just sent over the wire? Why do I have to do stuff like wrap it in a BufferedReader in order to get a single line and to know when there is something to read instead of having available() always return true? Ever heard of the select() system call!?!
Bad: library size. Man it can be a bitch to find what you want in the Java API docs. I know some complain about Python's module index size, but at least you can view it easily on a single web page and can figure out what you want from the names.
Bad: checked exceptions. I don't care what exceptions my methods might raise! If I did, I would read the docs to see what possible error conditions there are. Otherwise, let me be and don't force me to state every exception that might be raised because of some method I call! If you really want checked exceptions, fine. But limit where you have to declare them to the method that directly raises it and not all the way up the call chain. Documenting what can go wrong is up to each method and should not be forced upon me. I just end up leaving out the checked exceptions and just keep adding them until the compiler shuts up.
Good: Eclipse. Speaking of compilers, Eclipse really helped me keep my sanity, even if it is horribly slow on OS X. I normally code in Vim for Python and C work. But having incremental compilation and easy detection of compiler errors on the fly was really handy. And when I had to refactor into packages and rename some things, Eclipse made my life very simple (although they need to add a refactoring option of moving a module-visible class to a public class).
Good: enumerations. C's enumerations kind of suck since they are just syntactic sugar for ints and you can get around the type safety, let alone the fact that they are not within a namespace. Java's enumerations, on the other hand, are type-safe and exist in a specific namespace. And on top of that they can have methods and a constructor which makes them very handy for situations where you can only have a certain number of possibilities.
So that is my venting. I still think the language is crap and I always dread when I am made to use it. I think C# is definitely doing a better job than Java in terms of becoming the garbage-collected, statically typed, compiled language everyone should use.