Why Java Sucks
Topic: Rants
I've been really using Java now at work, and it's good enough, but I just have to vent about some of the things that annoy me.
So in no particular order:
1. Pain in the butt to do anything number-related.
For a bunch of reasons, Java has two ways to represent all the basic numerical values, both of which must be used if you are doing anything slightly complicated. For example, you can either use the double built-in type, or you can use the Double object. The double object lets you do normal arithmetic the way you'd expect:
double a = 1.0;
double b = 1.0;
double c = a + b;
But you can't do that with
Double because it's an object and Java doesn't allow operator overloading even for obvious cases for Sun-provided objects like
Double. You have to do clumsy things like:
Double a = new Double(1.0);
Double b = new Double(1.0);
Double c = new Double(a.doubleValue() + b.doubleValue());
So just use
double, right? Except you can't use
double in any of the built-in collections like
Array,
List, or
Map. The java collections all require real
Objects, so you're stuck wrapping your
double in a
Double to store it in an
Array, then unwrapping it to do any real work (like, say, addition) on it, then wrapping it all up in a
Double again when you need to put it back:
List inputs = new LinkedList();
List outputs = new LinkedList();
inputs.add(new Double(1.5));
Iterator li=inputs.iterator();
while(li.hasNext())
{
double result = 2.0 * ((Double)li.next()).doubleValue();
outputs.add(new Double(result));
}
Brilliant. This example also leads nicely into:
2. Collection elements are aways returned as Objects that must be cast back into something useful.
Java collections are powerful. You can store anything in them. Java handles this in a simple way by having all the collections work by taking Objects as the collection elements, and then forcing every other class to inherit from the base Object class. This lets you do stuff like:
List l = new LinkedList();
l.add(new Double(3));
l.add(new String("Hello"));
l.add(new LinkedList());
l.add(new Boat("Titanic"));
...because all of these objects are
Objects. But what if you
know what kind of list you want? Say you want an object method to take a list of
Persons?
public class Airplane {
board(List passengers) {
Iterator li=passengers.iterator();
while(li.hasNext()) {
seat((Person)li.next());
}
}
}
...
List passengers = new List();
passengers.add(new Person("Fred"));
passengers.add(new Person("Bob"));
passengers.add(new Person("Jill"));
passengers.add(new Bomb("Nuclear")); //no problem!
Airplane.board(passengers);
The
Airplane class can only see a list of objects that it trusts are
Persons, but someone could always insert something else into the list. If you want any kind of typechecking on the
List, you have to create yet another class that extends
List. In C++, for example, this kind of thing would be a one-liner using templates (which I'm not that fond of, but it beats the heck out of having yet-another-java-class).
3. 65535-Byte limit to amount of code in a member function.
Granted, you probably should never ever need methods this long, but this is still a retarded limitation to even have:
Exception in thread "main" java.lang.ClassFormatError: */*/*/* (Code of a method longer than 65535 bytes)
Oh, and this is a run-time limitation. The compiler won't catch you on this one, even though if
anyone knows the number of bytes in a method, the compiler should.
[For the record, I was trying something intentionally dumb for testing purposes (initializing an array with ~100,000 records) when I ran into this.]
Posted by wmschumach
at 1:01 AM PDT
Updated: August 17, 2004 4:45 PM PDT