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: http://blog.jooq.org/2013/01/12/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: http://blog.jooq.org/2012/06/01/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
Reference: Java, if this were a better world from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog.
WTF? Serializable and Cloneable very dangerous interface, once you publish you API, where class implemented serializable you can’t change it easily! More precisely it described in Effective Java by Joshua Bloch.
Do you mean that the class cannot be changed easily anymore? Why, because someone really clever thought that they ought to persist a serialised Java object on a disk for 15 years before deserialising it again? :-)
Firstly, yes. Someone, who use your library just update version and his production server lost important information, for example.
Now, imagine large java object (or simple thing, similar with linked list), it serialize recursively, one more unexpected Stack Overflow exception. Do you really want think about writeObject method for every class?
And, of course, security. Serializable can easyly break security of you classes. For example, you can modify inner state of your immutable objects!
So , in a better world, Java would be Python? :D
Looking into the post it would be Python + Ruby + .NET + Javascript + … and many more. :D
Why, yes. Stealing only the best ideas off of everyone.
type inference is so common these days … java should have it also, doesn’t make sense to me to tell the compiler twice about the type of my variable. String hello = “world”;
In the end, you’re probably right. I didn’t think all of this through very well (as I stated in my disclaimer). So the few advantages of making everything serialisable might indeed cause more problems in the end…