Java, if this were a better world

Just a little dreaming about a better world, where some old blunders in the Java platform would’ve been corrected and some awesome missing features would’ve been implemented. Don’t get me wrong. I think Java is awesome. But it still has some issues, like any other platform. Without any particular order, without claiming to be anything near exhaustive, and most importantly, without claiming to be well thought-through and entirely correct, I wish for these things:

Serialisability

Within an object, serialisability is the default. If you don’t want a member to be serialisable, you mark it “transient”. Why on earth do we have to add this silly marker interface “Serializable” to all of our classes?
All objects should be Serializable by default. Non-serialisability should be the “feature” that is marked explicitly
Of course, serialisability itself has a lot of weird details that I won’t go into, here

Cloning

Since all objects should be Serializable by default,
All objects should also be Cloneable by default. Non-cloneability should be the “feature” that is marked explicitly
Besides, shallow cloning is hardly ever useful. Hence
All objects should deep-clone themselves by default. Shallow cloning can be implemented explicitly
Note, the clone method should be some native method in java.lang.System or some other utility. It shouldn’t be on java.lang.Object, allowing client code to implement their proper interpretation of cloning, without any accidental name clashes. Alternatively, similar private callback methods could be implemented, the same way that this is done for serialisation, if cloning should be customised.

Unsigned numbers

Why isn’t this part of Java?
There should be an unsigned version of all integer primitives, as well as java.lang.Number wrappers

Primitives

Primitives are a pain to support in APIs. int and Integer should be the same from a syntax perspective. int[] and Integer[] should be, too
Primitives and their wrappers should be better integrated in the language and in the JVM
This one is probably not really resolveable without giving up on the performance advantage that true primitives offer. See Scala…

Properties

Getters and setters aren’t really state-of-the-art.
Properties should be supported more formally
See also a recent article and its comments on this blog: https://blog.jooq.org/bloated-javabeans-part-ii-or-dont-add-getters-to-your-api/

Collections

The collection API should be better integrated with the language. Like in many other languages, it should be possible to dereference collection contents using square brackets and curly braces. The JSON syntax would be an obvious choice. It should be possible to write:

// Translates to new ArrayList<>(...);
List<Integer> list = [ 1, 2, 3 ];

// Translates to list.get(0);
Integer value = list[0];

// Translates to list.set(0, 3);
list[0] = 3;

// Translates to list.add(4);
list[] = 4;

// Translates to new LinkedHashMap<>(...);
Map<String, Integer> map = { "A": 1, "B": 2 }; 

// Translates to map.get(0);
Integer value = map["A"]

// Translates to map.put("C", 3);
map["C"] = 3;

ThreadLocal

ThreadLocal can be a nice thing in some contexts. Probably, the concept of ThreadLocal isn’t 100% sound, as it can cause memory leaks. But assuming that there were no problems,
threadlocal should be a keyword, like volatile and transient
If transient deserves to be a keyword, then threadlocal should be, too. This would work as follows:

class Foo {
  threadlocal Integer bar;

  void baz() {
    bar = 1;           // Corresponds to ThreadLocal.set()
    Integer baz = bar; // Corresponds to ThreadLocal.get()
    bar = null;        // Corresponds to ThreadLocal.remove()
  }
}

Of course, such a keyword could be applied to primitives as well

References

References are something weird in Java. They’re implemented as Java objects in the java.lang.ref package, but treated very specially by the JVM and the GC.
Just like for threadlocal, there should be keywords to denote a reference
Of course, with the introduction of generics, there is only little gain in adding such a keyword. But it still feels smelly that some classes are “very special” within the JVM, but not language syntax features.

Reflection

Please! Why on earth does it have to be so verbose?? Why can’t Java (Java-the-language) be much more dynamic? I’m not asking for a Smalltalk-kind of dynamic, but couldn’t reflection be built into the language somehow, as syntactic sugar?
The Java language should allow for a special syntax for reflection
Some pain-easing can be achieved on a library-level, of course. jOOR is one example. There are many others.

Interfaces

Interfaces in Java always feel very weird. Specifically, with Java 8’s extension methods, they start losing their right to exist, as they move closer to abstract classes. Of course, even with Java 8, the main difference is that classes do not allow multiple inheritance. Interfaces do – at least, they allow for multiple inheritance of specification (abstract methods) and behaviour (default methods), not for state. But they still feel weird, mainly because their syntax diverges from classes, while their features converge. Why did the lambda expert group decide to introduce a default keyword?? If interfaces allow for abstract methods (as today) and concrete methods (defender methods, extension methods), why can’t interfaces have the same syntax as classes? I’ve asked the expert group with no luck: http://mail.openjdk.java.net/pipermail/lambda-dev/2012-August/005393.html Still, I’d wish that…
Interface syntax should be exactly the same as class syntax, wherever appropriate
This includes static methods, final methods, private methods, package-private methods, protected methods, etc.

Default visibility

Default visibility shouldn’t be specified by the absence of a private/protected/public keyword. First of all, this absence isn’t dealt with the same way in classes and interfaces. Then, it is not very readable.
Default visibility should be specified by a “package” or “local” or similar keyword

Literals

This would be an awesome addition in everyday work.
There should be list, map, regex, tuple, record, string (improved), range literals
I’ve blogged about this before: https://blog.jooq.org/array-list-set-map-tuple-record-literals-in-java/ Some ideas mentioned by Brian Goetz on the lambda-dev mailing list were found here: http://mail.openjdk.java.net/pipermail/lambda-dev/2012-May/004979.html
#[ 1, 2, 3 ]                          // Array, list, set
#{ "foo" : "bar", "blah" : "wooga" }  // Map literals
#/(\d+)$/                             // Regex
#(a, b)                               // Tuple
#(a: 3, b: 4)                         // Record
#"There are {foo.size()} foos"        // String literal
I’ll add
#(1..10)                              // Range (producing a List)

Final

Methods, attributes, parameters, local variables, they can all be declared as “final”. Immutability is a good thing in many ways, and should be encouraged (I’ll blog about this, soon). Other languages, such as Scala, distinguish the “val” and “var” keywords. In addition to those other languages’ impressive type inference capabilities, in most cases, val is preferred to var. If one wants to express a modifiable variable, they can still use “var”
Final should be the default behaviour for members, parameters and local variables

Override

It is dangerous to accidentally override a method. Other languages have solved this by causing compilation errors on overrides
An override keyword should be introduced to explicitly override a method
Some Java compilers (e.g. the Eclipse compiler) can be configured to emit a warning / error on the absence of the java.lang.Override annotation. However, this really should be a keyword, not an annotation.

Modules

Dependency management is a nightmare in Java. There is one other language, that builds compilation units in terms of modules: Fantom. Stephen Colebourne (the JodaTime guy) is a big fan of Fantom, and has held a speech at Devoxx. He also blogs about Fantom, from time to time: http://blog.joda.org/search/label/fantom
A compilation unit should be expressed in the form of a “module” / jar file
This would of course make Maven obsolete, as the Java compiler could already handle dependencies much better.

Varargs and generics

Come on. @SafeVarargs?? Of course, this can never be resolved entirely correctly, due to generic type erasure. But still
There should be no generic type erasure

Tuples and Records

I really think that this is something missing from Java
There should be language support for tuples and records
Scala has integrated tuples up to a degree of 22, .NET supports tuples up to a degree of 8. This would be a nice feature in the Java language as well. Specifically, records (or structs) would be a nice thing to have. As mentioned before, there should be literals for tuples and records, too. Something along these lines:
#(a, b)                               // Tuple
#(a: 3, b: 4)                         // Record

Compiler

A compiler API that goes far beyond adding some annotation processing would be nice. I’d love to be able to extend Java-the-language itself. I’d like to embed SQL statements directly into Java code, similar to SQL being embeddable in PL/SQL. Of course, such SQL code would be backed by a library like jOOQ.
The compiler API should allow for arbitrary language extension
Of course, this improved compiler API should be done in a way that auto-completion, syntax highlighting and other features work automatically in IDEs like Eclipse, as the compiler extensions would be able to expose necessary artefacts to IDEs. OK, I agree, this improvement is a lot of dreaming :-)

Type inference

If unambiguous, couldn’t type inference just be as powerful as Scala’s? I don’t want to write down the complete type of every local variable.
Scala’s local type inference should be supported

Operator overloading

OK, this is a highly religious topic. Many of you won’t agree. But I just like it
Java should support operator overloading
Some library operations are just better expressed using operators, rather than methods. Think of BigInteger and BigDecimal’s horribly verbose API.

Any other ideas? Add comments!

Of course, lambdas and extension methods are missing and generics are erased. While the latter will never be fixed, the first will be in Java 8. So lets forgive Sun and Oracle for making us wait so long for lambdas

15 thoughts on “Java, if this were a better world

  1. Some things I’ll add that are not really coming in Java 8.

    1. Light weight processes. Either Actors or Green Threads with a Promise API (ie Future Pipelining)
    2. Along with number #1 perhaps a Grand Central Dispatch
    3. Named parameter Constructors for Immutable Object construction
    4. Pruning of needless Java API (corba comes to mind) for faster start-up time and smaller jars.
    5. More Immutable data structures.
    6. Easier Async IO (NIO)
    7. Async version of JDBC — big undertaking

    1. #3: Yes! I forgot named parameters. I’d love to see that for any type of method, not just constructors. It’s incredible that parameter names aren’t even available through reflection. They’re utterly erased by the compiler.
      #4: Oh yes. We should finally get a J2SE 2.0 (after 1.8)
      #5: Care to explain?
      #7: This is probably hard to guarantee for all databases…

      1. I think you cover a large part of #5 with records and tuples but I think there should be some interfaces like ImmutableList and ImmutableMap … I don’t think its possible to add something like that now or even later but it would have been nice.

        As for type inference I totally agree with you. I would only want it locally in a method. Anything higher up gets very confusing. That is public methods should explicitly state their types.

        Not that I don’t like Scala or Groovy but I’m glad Java forces you to do certain things like not omitting semi colons and parens. Also operator overloading in Scala is very confusing specifically when combined with type inference.

        My problem with Scala and Groovy is that while its easier to write code its much more difficult to read other people’s code and debug. I have found using Scala and Groovy with a team of developers rather unpleasant. That is one thing I like about Java… being consistent and verbose can be a good thing (remember Perl :) ).

        1. Aha, yes. ImmutableList with only contains(), get(), indexOf(), iterator() and other non-modifying methods would be awesome.

          Hehe, yes, Scala is the new Perl, definitely! Anyway, it’s a good idea pool and playground for features that will (might, hopefully) eventually move back to Java.

  2. Hi, nice article at the first place. I like this blog! One thing I would like to add – unmanaged code in .NET way with keyword “using”.

  3. Hihi it looks you are a C#/.net developer :)
    I actually migrated from Java (8 years experience) to C# in the last month and I can write the same post .. about C# WHYY C# whyy WHY do we have both interfaces and delegates when we are fine without delegates why do we have new override and virtual and missing and all sort of weird things why milions of stuffs (the only thing I do like are generics) so I can say .. JUST ADAPT .. and thats it… I do not like the default keyword for interfaces as well but I guess the reason is to say “shh this is black magic.. if you have 2 default methods in 2 interfaces with same signature and you try to implement both of them in your class you wont have default method” if there was no default .. then everyone will think but I do have implementation .. now you dont have to think YOU have “default” weird implementation not real one

    1. Clearly, you shouldn’t miss my disclaimer:

      “without claiming to be well thought-through”

      ;-). No I’m not a C# / .NET developer. I’ve just observed a couple of features in C#, Scala, Python, Ruby, JavaScript and many other languages, that I’d wish I could use in my every day Java work.

  4. Serialization by default would be rather problematic for several reasons. By one hand among serialization breaks encapsulation. Once you serialize an object you expect to be capable of deserializing it, which means you are not allowed to change the internal representation of the object without breaking it or having to deal with multiple versions of it, which is ultimately problematic. So, once you introduce serialization of objects you have to deal with the difficulties of evolving your API. Now, you cannot even think that the private state of the class can change without breaking pre-existing objects out there. On other hand the object serialization system allows a bytestream to be produced from a graph of objects, sent out of the Java environment (either saved to disk or transmitted over the network) and then used to recreate an equivalent set of new objects with the same state. What happens to the state of the objects outside of the environment is outside of the control of the Java system (by definition), and therefore is outside the control of the security provided by the system. The question then arises: once an object has been serialized, can the resulting byte array be examined and changed in a way that compromises the security of the Java program that deserializes it? So, serialization imposes a set of security issues that are quite important. So, making all the objects serializable by default, in my opinion, it is not a good idea. I think we would invest more time trying to make them transient. I do believe serialization in Java should have been different, perhaps somewhat similar to what JAXP or other XML serialization frameworks do today.

    1. I’m sure that there would be lots of new issues that arise from serialisability by default. But most of the time, we wouldn’t care that much about those issues, as most of the time, the systems we design aren’t so clever that we should think of everything.

      But when we work inside a container, where short-lived things have to be stored in a session once in a while / or transmitted over the network, it’s just so tedious to explicitly mark everything as Serializable.

      So, along the lines of your argumentation, things could be “Serializable” by default, but not “Persistable”, or “Storeable” by default. In other words, long-term serialisation, and thus deserialisation after months or years, is the real problem. But then again, you’re probably nuts for using Serialisation in that case (already today). You better serialise things into a well-defined protocol, that is implementation-independent

  5. Regarding your comments about defender methods, it has been subject of discussion in the user’s group. The default methods do not behave exactly the same as any other virtual methods. For instance, if a method is defined in a superclass, and then a subclass inherits a method and at the same time implements a interface with a method with the same signature that has a default method, the superclass will win against the default method. So the use of the keyword “deault” makes it evident that the method is not just another virtual method, but something the represents the “default behavior” of no other is provided more specifically elsewhere. Stephen Colebourne, the creator of Joda Time and new Date/Time API in Java 8 presented your same concerns in the Lambda Mailing list almost a year before your question in the same list. I leave the reference here in case you consider it valuable (https://mail.openjdk.java.net/pipermail/lambda-dev/2011-December/004356.html)

    1. I’ve seen Steven Colebourne’s mail (after writing my own). I still think that this is an irrelevant implementation detail, that jumps at us in 5% of the cases, whereas in most cases, we really don’t care about this “defaultness”. These facts just don’t deserve their own syntax.

      The “diamond” problem already existed for constants. No one had this wacko idea of requiring a “default” keyword on interface constants, because “heck, the super class wins when shadowing the constant from the interface” ;-)

      … OK, just double-checked to get my facts straight. For constants, there’s no “winning”, there is ambiguity. I guess the situation is a bit different as they’re static…

  6. There are some points regarding primitives, for example. I just completely disagree with some otheres: serializable by default (why even?), cloning (from previous point + cost), ThreadLocal as a keyword (so there are yet more strange assumptions about the threading model in lib code, right?)… This wouldn’t be a better world.

    1. This doesn’t need to be a vision about a realistic better world. But the amount of effort that goes into implementing manual serialisation of Java objects (e.g. via XML, JSON, whatever protocol, or even tweaking the existing serialisation) can be tremendous… The same is true for cloning, although probably, an immutable data model is a better approach than making it easy to clone mutable data structures.

Leave a Reply