Some Reasons Why I Hate Java

Posted by Vic's Blog on April 3, 2016

I’ve been programming in java for about five years now. In fact it was the first programming language I really “mastered”. Learning it was quite easy, but not because its a nice language. It’s because of its immense lack of features. But I’ll get back to that later.

I got used to it. I even liked it. Mainly because I didn’t know anything else. I got used to its concepts or rather, its one concept. Java is Object Oriented and that’s the one paradigm you are allowed to use. Nothing else. (This isn’t exactly true anymore as of recent Java 8 but I found enough reasons to hate its awe so impressive Functional Programming as well.)

The most common example to show what that means is Java’s “Hello World”:

// In File HelloWorld.java
public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello World!");
  }
}

Doesn’t look that bad, right? But now let me show you the same thing in Perl:

print "Hello World!";

They both share the same cancer that is called “semicolon” so here’s a more pure version in Python that looks almost the same:

print "Hello World!"

As you can see, a 5 to 1 line ratio that holds up for pretty much all of the time. In Java everything has to be tied to Objects. Functions aren’t first-class citizen. Java practically invented the ugly and useless singleton pattern since people were tired of writing “static”. Plus, Instances can implement interfaces (Lack of traits and mutliple inheritance) but Classes can’t. Therefore you need something like this:

public interface SomeInterface {
  void someMethod();
}

public final class Singleton implements SomeInterface { // The final isn't really needed but its "Good practice"
  private Singleton() {} // We don't want another instance of this, so private constructor
  public static Singleton instance = new Singleton(); // Singleton instance
  
  // Some fields here
  ...
  
  @Override
  public void someMethod() {
    // Do something here
  }
  
  // Some other methods here
  ...
}

...
// And then you can do this:
System.out.println(Singleton.instance instanceof SomeInterface); // true
Singleton.instance.someMethod(); // Calls some method on the instance

Tired of writing Singleton.instance all the time yet? Well, you are out of luck, you need to write static “bridge methods” in order to get rid of that limitation or assign it to a variable.

It doesn’t have to be like that. Scala (Which is an awesome replacement for Java running on the JVM, highly recommend!) introduces object:

trait SomeTrait {
  def someMethod() {
    // Some implementation here
  }
}

object Singleton extends SomeTrait {  
  // Some fields here
  ...
  // Some other methods here
}

println(Singleton.isInstanceOf[SomeTrait]) // true
Singleton.someMethod()

No semicolon, no workaround. Who said that wasn’t possible? This way scala also solves Java’s four line “Hello World!” puzzle:

object Main extends App {
  println("Hello World!")
}

Was this black magic? No. A properly designed language can make everything look beautiful. Java wasn’t designed to look beautiful, it was designed to be reliable and maintainable. It was created to be fed to a mob of code monkeys at an enterprise and not to be fun to write. If you don’t happen to be a million dollar enterprise, then don’t use Java.

Java as a language is crippled to its core. It was designed to get rid of all possible abuses. Every piece of Java code has to follow the same scheme, be instantly understood by all those code monkeys. Do you really need this if you are just a hobbyist? No.

My problem was that I didn’t know of a better alternative. I was taught java at school, as first (and only) programming language. And why is that? Because their aim is to make you ready for the business world, and eveybody there uses Java. It doesn’t matter if you understand the diversity of concepts and programming languages. It doesn’t matter if you understand how your OS works under the hood. All that matters is that you are going to be a productive wheel in society. Programming can be fun, and Java manages to kill it at its core.

Remember the Hello world example? In order to understand it you have to know what a class is. You have to know what visibility is, you have to know what a static method is. You need to be familiar with the object notation. And then, after you understood all of these you are able to output ONE LINE to the console. Great. No wonder that I don’t have any friends at school that program.

Java got rid of every feature that makes a language interseting and fun to write in. And on top of that the compiler is just dumb. It can’t solve the easiest problems. Why is there no multiple inheritance? Because it would have been effort to implement that. All of this creates redundancy on the programmers end. In fact the Java compiler is too dump to find a class if it doesn’t declare the package on the first line. Why is this needed, you might ask, in Java the folder structure has to match the packages? The only answer I can think of is that it would have been extra effort to implement.

// In file moe/nightfall/vic/integratedcircuits/API.java
package moe.nightfall.vic.integratedcircuits; // WHY DO I HAVE TO WRITE THIS?!

public class API implements IAPI { // WHY DO I HAVE TO WRITE THIS? 
// You can only declare one top level class per file ANYWAYS!
  ...
}

The obvious alternative to this would have been:

class API implements IAPI;
...

The IDE can handle this you might say. Of course it can, duh. But why does it have to? It’s another step to take before you can even start programming. You have to understand what an IDE is first.

With Python you can create one file, put print "Hello World!" in it and run with py helloworld.py and you are programming!

Or even shorter, you just write py and start the interactive console and you are programming! It was just that simple!

Oracle’s flow chart for including a new feature in Java looks like this:

Flow Chart

They find the most ridiculous excuses to not include a feature. In java you have to declare every type twice. Look at this:

ArrayList<String> list = new ArrayList<String>(); // The "old" way
ArrayList<String> list = new ArrayList<>(); // The "new" way
// The obvious  way
// var list = new ArrayList<>();

Then how does the IDE magically know what type a variable is supposed to be? The compiler does, too, but for some reason you still have to type it twice. A feature like this was proposed once around here: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4459053

To quote the reply:

Humans benefit from the redundancy of the type declaration in two ways. First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns.

Maybe its just me but hmm, perhaps, getMap() returns a MAP?

Despite basically forcing IDEs on us they don’t trust them to add a highlight with the returned type? Silly.

Another famous example is operator overloading. Java is allowed to do that for the built in type String but you, the programmer, can’t be trusted to use it in a sensible way. A great example for the idiocy of this is Java’s BigDecimal. Look at this: r

// Of course, they have Bignums now (ha!) All you have to do (ha!) is rewrite your code to look like this:
result = x.add(y.multiply(BigInteger.valueOf(7))).pow(3).abs().setBit(27);

I don’t want to figure out what it does. This code is insulting me. I don’t want to read it.

In any (reasonable) language with operator overloading it could look like this:

result = abs((x + y * 7) ** 7) | (1 << 27) 

Don’t quote me on the transcription, I might as well have confused a bracket or two.

Of course the same thing holds true for vectors or matrices where operator overloading is absolutely reasonable.

It doesn’t end here, obviously. The next really annoying thing is that there are no literals for anything but strings. Strings can’t span multiple lines of course and there is no string interpolation, but whom am I telling this.

Have a look at this awesome table literal from lua:

something = {
  propery = 'value',
  foo = bar,
  bar = 1337
}

Of course this doesn’t make much sense for static typing, but sometimes you just want a map of strings. You have several different flavors of horror for this in Java:

// The Vanilla way
Map<String, String> map = new HashMap<String, String>(); // IDEs usually autocomplete this, the <> is barely ever used
map.put("property", "value");
map.put("foo", bar);
map.put("bar", String.valueOf(1337));

// The Antipattern way, this creates an anonymous class! Do not use!
Map<String, String> map = new HashMap() {{
  put("property", "value");
  put("foo", bar);
  put("bar", String.valueOf(1337));
}};

// With guava
Map<String, String> map = ImmutableMap.of (
  "property", "value",
  "foo", bar,
  "bar", String.valueOf(1337)
)

The guava one looks somewhat okay but don’t forget that it has to construct it at runtime, allocating a useless array and iterating it! I guess it suits Java’s memory management of “Create a trillion objects a second and let the garbage collector hang the host system!”. A map literal could be converted into the corresponding calls are compile time, zero overhead.

There have been several proposals for collection literals but not a single one made it. Not suprising.

Looking at C#, meanwhile:

var map = new Dictionary<string, string> {
  ["property"] = "value",
  ["foo"] = bar
};

But Java remains the black sheep in the horde.

I could continue like this forever and give more examples like the lack of typedef but I think you get what I’m trying to say. Perhaps I’ll create another post dedicated to examples and then I can explain why Java 8’s Lambdas suck as well.

TL;DR

Stop teaching Java at schools as first programming language. It kills off everything that’s fun about programming before you can even start to programm anything. Stop using Java for non enterprise projects (It’s not worth it anyways, Swing sucks) and instead use one of the many derivatives like Scala, Groovy or Kotlin if you rely on the JVM.